为什么以下非静态数据成员初始化在C ++ 11中无效

时间:2014-07-09 17:11:38

标签: 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> foo;

    std::cout << "Rank: " << foo.rank << std::endl;

    return 0;
}

它没有使用gcc-4.8.1编译,抱怨在成员声明结束时缺少;并且在...令牌之前缺少预期的非限定id。但是,如果我用以下内容替换这两个成员,它将按预期编译并工作:

const std::size_t     rank = 5;
const std::size_t     dimensions[5] = {1, 2, 3, 4, 5};

为什么我不能使用sizeof...Sizes...作为编译时常量,肯定两者都是在编译时已知和评估的,因此可以用于非静态数据成员初始化?此外,如果我将rank = 5替换为rank = sizeof(int),它会按预期编译并运行,因此sizeof似乎不会出现问题。


这是我的demonstrative ideone

2 个答案:

答案 0 :(得分:7)

这是gcc bug 57673,已在gcc 4.9中修复。 gcc 4.8的修复是添加一组额外的括号。

const std::size_t rank = (sizeof...(Sizes));

Live demo

答案 1 :(得分:2)

如@Brian所述,您的代码适用于GCC 4.9。

我发现在GCC 4.8上你可以通过将扩展包装在括号中来使其工作:

const std::size_t    rank = (sizeof...(Sizes)); // OK