在这个问题中,我将参考我之前的问题.
在那个问题中,我发现以下内容无效:
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)
实际上,它似乎有效,所以感谢提出它的人.
无论如何,我不明白为什么这是有效的代码,而前一个不是.
它是否应该受到先前解决方案的模糊性的影响?在这种情况下,编译器为什么以及如何解决这种模糊性?
根据上一个问题(参见本问题开头的链接),在我看来,仍然可变参数部分应该将任何参数填充到最后,因此该代码也不应该是有效的.
当然,我错了,但在我的推理中究竟出了什么问题?
嗨,我想知道是否可以简单地用SDL2截取屏幕截图.我试过SDL_GetWindowSurface
但是我得到一个错误说:
没有可用的硬件加速渲染器.
我从这里拿了代码.
我想到的另一个解决方案是将纹理转换为表面,但我没有设法做到这一点......
你有什么解决方案吗?
请考虑以下代码:
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'
问题很简单:我错过了什么?
考虑下面的最小例子:
#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)作为左值
这背后的理由是什么?
我想这是正确的,但我想了解我能用所有类型而不是非类型的方式做到这一点的原因.
如果我有一个模板:
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
.
我希望这是有道理的.
注意:我正在向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++中的类型,包括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)
我想将此枚举的每个值映射到某种类型.我要地图AGE
来int
,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) 我正在编写一些程序来通过代码生成自动调用一些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
这是对这个问题的后续跟进.
请考虑以下代码:
#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
放入返回类型或类似方法.
我有创建函数的问题,对于给定的类型,如果它是从其他人那里做的事情,而对于所有其他情况做其他事情.我的代码:
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
.有什么建议?