小编sky*_*ack的帖子

变量模板,参数包及其在参数列表中讨论的歧义

在这个问题中,我将参考我之前的问题.

在那个问题中,我发现以下内容无效:

template<typename T, typename... A, typename S>
class C { };
Run Code Online (Sandbox Code Playgroud)

这是因为:

[它不是有效的代码]用于类模板,因为必须始终指定它们的参数,这将始终导致歧义,除非参数包在最后并且填充任何剩余的模板参数.

这是有道理的,当然,我得到了它.

然后,作为替代方法,提出了涉及专业化的以下内容:

template<typename F, typename S>
class C;

template<typename T, typename... A, typename S>
class C<T(A...), S> { };
Run Code Online (Sandbox Code Playgroud)

实际上,它似乎有效,所以感谢提出它的人.

无论如何,我不明白为什么这是有效的代码,而前一个不是.
它是否应该受到先前解决方案的模糊性的影响?在这种情况下,编译器为什么以及如何解决这种模糊性?
根据上一个问题(参见本问题开头的链接),在我看来,仍然可变参数部分应该将任何参数填充到最后,因此该代码也不应该是有效的.
当然,我错了,但在我的推理中究竟出了什么问题?

c++ templates variadic-templates c++11

11
推荐指数
1
解决办法
246
查看次数

SDL2 C++截图

嗨,我想知道是否可以简单地用SDL2截取屏幕截图.我试过SDL_GetWindowSurface但是我得到一个错误说:

没有可用的硬件加速渲染器.

我从这里拿了代码.

我想到的另一个解决方案是将纹理转换为表面,但我没有设法做到这一点......

你有什么解决方案吗?

c++ screenshot sdl-2

10
推荐指数
1
解决办法
7438
查看次数

别名模板,部分特化和无效参数类型void

请考虑以下代码:

template<typename F>
struct S;

template<typename Ret, typename... Args>
struct S<Ret(Args...)> { };

template<typename... Args>
using Alias = S<void(Args...)>;

int main() {
    S<void(int)> s;
    Alias<int> alias;
}
Run Code Online (Sandbox Code Playgroud)

它正常工作,如预期的那样,涉及的线S和涉及Alias引擎盖的相同类型S<void(int)>.

现在,请考虑以下更改:

int main() {
    S<void(void)> s;  // this line compiles
    Alias<void> alias;  // this line does not
}
Run Code Online (Sandbox Code Playgroud)

我期望它编译,原因与上面提到的类似.
不言而喻,由于涉及到行,它不会编译Alias,而是我收到错误:

用'Alias = S [with Args = {void}]代替'模板'

[...]

错误:参数类型无效'void'

问题很简单:我错过了什么?

c++ templates void c++11 template-aliases

10
推荐指数
1
解决办法
303
查看次数

xvalues:非类类型和类类型之间的差异

考虑下面的最小例子:

#include<utility>

struct S { };

int main() {
    S s;
    std::move(s) = S{};
}
Run Code Online (Sandbox Code Playgroud)

它编译没有错误.
如果我改用非类型,我会收到错误.
例如,下面的代码无法编译:

#include<utility>

int main() {
    int i;
    std::move(i) = 42;
}
Run Code Online (Sandbox Code Playgroud)

枚举,作用域枚举等也会发生同样的情况.
错误(来自GCC)是:

使用xvalue(rvalue reference)作为左值

这背后的理由是什么?

我想这是正确的,但我想了解我能用所有类型而不是非类型的方式做到这一点的原因.

c++ move rvalue xvalue c++11

10
推荐指数
2
解决办法
336
查看次数

存储和重新使用decltype值?

如果我有一个模板:

template <class T>
struct Item
{
  T _value;
};
Run Code Online (Sandbox Code Playgroud)

然后我可以这样做:

// ...
Item<int> x = { 42 }; // declared as an int

// ...
decltype(x._value) y = 20; // 'y' is also an int
Run Code Online (Sandbox Code Playgroud)

但是可以将decltype变量存储到变量中以便以后使用吗?

为什么?
我想将项的值存储为指针.

有点像std::vector<Item*>但是因为它们是模板我必须将它们存储为指针void:

std::vector<void*> is;
is.push_back(new Item<int>());
is.push_back(new Item<double>());
is.push_back(new Item<float>());
Run Code Online (Sandbox Code Playgroud)

这一切都很好,但是当需要删除指针时,我需要将我的void*表格重新转换为正确的类型(因此调用析构函数):

delete (Item<int>*)is[0];
Run Code Online (Sandbox Code Playgroud)

如果我知道类型,我可以这样做:

delete (Item<decltype(whatever)>*)is[0];
Run Code Online (Sandbox Code Playgroud)

因此我需要存储的原因decltype.

我希望这是有道理的.

c++ templates decltype c++11

10
推荐指数
2
解决办法
819
查看次数

通用lambda,继承和尾随返回类型:这是有效的代码吗?

注意:我正在向clang打开一个问题,但我想确保我的代码也是有效的.


我试图回答另一个答案,我在玩lambdas和继承时发现了一些困难.
考虑以下最小的例子:

template<typename Func>
struct Base: Func {
    Base(Func func): Func{func} {}

    template<typename... Args>
    auto operator()(Args... args)
    -> decltype(Func::operator()(args...), void()) {
        Func::operator()(args...);
    }
};

int main() {
    auto l = [](auto &&) {};
    Base<decltype(l)> mixin{l};
    mixin(0);
}
Run Code Online (Sandbox Code Playgroud)

GCC 6.1 编译它,叮叮4.0 崩溃.
请注意,使用以下定义编译都很好:

auto l = [](int) {};
Run Code Online (Sandbox Code Playgroud)

这是有效的代码还是我正在做标准不允许的事情?


是我刚刚打开的问题的链接.

c++ gcc clang language-lawyer c++14

10
推荐指数
1
解决办法
388
查看次数

将枚举值映射到C++中的类型

有没有办法将枚举值映射到C++中的类型,包括C++ 11.
我有以下枚举类型:

enum ATTRIBUTE{AGE=0, MENOPAUSE, TUMOR_SIZE, INV_NODES, NODE_CAPS,
               DEG_MALIG, BREAST, BREAST_QUAD, IRRADIAT, CLASS};
Run Code Online (Sandbox Code Playgroud)

我想将此枚举的每个值映射到某种类型.我要地图AGEint,MENOPAUSE另一个枚举类型,BREAST为bool等等.
那么是否可以创建一个函数来返回一个取决于attr变量值的类型值?

//Like that:
auto value = map_attr(ATTRIBUTE attr);
//Here the type of the value variable should be int if the attr variable is AGE, bool for BREAST and so on.
Run Code Online (Sandbox Code Playgroud)

c++ enums metaprogramming template-meta-programming c++11

10
推荐指数
1
解决办法
4330
查看次数

元编程技巧:如何简化两个元函数的实现

我正在编写一些程序来通过代码生成自动调用一些API.
在某些情况下,我需要从一个类型转换Source为一个类型Target,但这些类型装饰有指针,const等.所以我需要做的是删除所有装饰,如指针,常量,数组等,得到普通类型将其映射到另一种类型,然后将装饰应用回新类型.

该实现有许多模板专业化.代码后的问题.我不能使用constexpr元编程,因为我需要使用VS2013.

template <class T>
struct TypeIs {
    using type = T;
};

template <class T>
struct GetPlainType : TypeIs<typename std::decay<T>::type> {};

template <class T>
struct GetPlainType<T&> : TypeIs<typename GetPlainType<T>::type> {};

template <class T>
struct GetPlainType<T const &> : TypeIs<typename GetPlainType<T>::type> {};

template <class T>
struct GetPlainType<T &&> : TypeIs<typename GetPlainType<T>::type> {};

template <class T>
struct GetPlainType<T const &&> : TypeIs<typename GetPlainType<T>::type> {};

template <class T>
struct GetPlainType<T*> : TypeIs<typename GetPlainType<T>::type> …
Run Code Online (Sandbox Code Playgroud)

c++ metaprogramming type-traits template-specialization c++14

9
推荐指数
2
解决办法
499
查看次数

在专业化的情况下,检查保护参数包是否导致格式错误的程序?

这是对这个问题的后续跟进.

请考虑以下代码:

#include <type_traits>

template<typename T, typename... P, typename U = std::enable_if_t<std::is_integral<T>::value>>
void f() { static_assert(sizeof...(P) == 0, "!"); }

int main() {
    f<int>();
}
Run Code Online (Sandbox Code Playgroud)

它编译,但根据[temp.res]/8它是不正确的,不需要诊断,因为:

可变参数模板的每个有效特化都需要一个空模板参数包

现在考虑这个略有不同的例子:

#include <type_traits>

template<typename T, typename... P, typename U = std::enable_if_t<std::is_integral<T>::value>>
void f() { static_assert(sizeof...(P) == 0, "!"); }

template<>
void f<int, int>() { }

int main() {
    f<int, int>();
}
Run Code Online (Sandbox Code Playgroud)

在这种情况下,存在有效的完全显式特化,参数包不为空.
这是否足以说代码不再格式错误?


注意:我不是在寻找替代方法,例如将其std::enable_if_t放入返回类型或类似方法.

c++ templates language-lawyer variadic-templates c++11

9
推荐指数
1
解决办法
237
查看次数

带有std :: is_base_of的派生类的C++模板函数

我有创建函数的问题,对于给定的类型,如果它是从其他人那里做的事情,而对于所有其他情况做其他事情.我的代码:

class BaseClass {};
class DerivedClass : public BaseClass {};

template <typename T>
void Function(typename std::enable_if<std::is_base_of<BaseClass, T>::value, T>::type && arg) {
    std::cout << "Proper";
}

template <typename T>
void Function(T && arg) {
    std::cout << "Improper";
}

void test() {
    Function(DerivedClass{});
}
Run Code Online (Sandbox Code Playgroud)

对于班级DeriviedClass和其他基于BaseClass我想称功能couting Proper,但它couts Improper.有什么建议?

c++ templates metaprogramming c++11

9
推荐指数
2
解决办法
3864
查看次数