C++ 为什么以下非静态数据成员初始化在C++;11
我尝试编译以下小示例:C++ 为什么以下非静态数据成员初始化在C++;11,c++,templates,c++11,initialization,variadic-templates,C++,Templates,C++11,Initialization,Variadic Templates,我尝试编译以下小示例: template <typename T, std::size_t... Sizes> class Foo { public: const std::size_t rank = sizeof...(Sizes); const std::size_t dimensions[sizeof...(Sizes)] = { Sizes... }; }; int main() { Foo<int, 1, 2, 3> f
template <typename T, std::size_t... Sizes>
class Foo {
public:
const std::size_t rank = sizeof...(Sizes);
const std::size_t dimensions[sizeof...(Sizes)] = { Sizes... };
};
int main()
{
Foo<int, 1, 2, 3> foo;
std::cout << "Rank: " << foo.rank << std::endl;
return 0;
}
为什么我不能使用sizeof…
和sizeof…
作为编译时常量,当然这两个常量都是在编译时已知和计算的,因此可以在非静态数据成员初始化中使用?此外,如果我用rank=sizeof(int)
替换rank=5
,它会按照预期编译和工作,因此sizeof
似乎没有问题
这是我的名片 正如@Brian所提到的,您的代码在GCC4.9上确实有效 我发现在GCC4.8中,可以通过将扩展包括在括号中来实现:
const std::size_t rank = (sizeof...(Sizes)); // OK
这是gcc 4.9中修复的。GCC4.8的修复方法是添加一组额外的括号
const std::size_t rank = (sizeof...(Sizes));
在上工作。顺便说一句:你的打字错误是:
std::size
而不是开头的std::size\u t
@DanielFrey我添加了我的演示性ideone汇编;打字错误只是我把它抄错了哈哈!你忘记启用C++11了吗?至少在ideone中你做到了。您需要在ideone中将语言更改为C++11。使用g++即-std=c++11
使用c++11的实际表意文字示例:。coliru使用GCC4.9.0,而ideone使用4.8.1。@leemes它声明默认情况下启用了-std=c++11
,当时它发出警告,告诉我这是c++11独有的功能。您还可以将它们转换为静态constepr
,而不是非静态成员(这有一些额外的好处,IMHO)@MadScienceDreams有趣的是,对于一个静态数据成员来说,修复了一个似乎是解析问题的问题。我猜,因为使用静态const值更常见(主要是因为如果它是const并且总是相同的,那么为什么要为它分配内存呢?而且静态const更容易解析为constexpr,所以它们可能更快),这在早期就被发现了。它们都有不同的规则(因为const成员的内联声明有自己的奇怪规则)。
const std::size_t rank = (sizeof...(Sizes));