Reputation: 5980
I have tried to compile the following small example:
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;
}
It does not compile with gcc-4.8.1 complaining of a lack of ;
at end of member declaration and a lack of expected unqualified-id before ...
token. However, if I replace the two members with the following it compiles and works as expected:
const std::size_t rank = 5;
const std::size_t dimensions[5] = {1, 2, 3, 4, 5};
Why can I not use sizeof...
and Sizes...
as compile-time constants, surely both are known and evaluated at compile time and so can be used in non-static data member initialization? Moreover, if I replace rank = 5
with rank = sizeof(int)
it compiles and works as expected, so it doesn't appear to be a problem with sizeof
.
Here is my demonstrative ideone.
Upvotes: 2
Views: 171
Reputation: 109119
This is gcc bug 57673 that was fixed in gcc 4.9. The fix for gcc 4.8 is to add an extra set of parentheses.
const std::size_t rank = (sizeof...(Sizes));
Upvotes: 7
Reputation: 35485
As mentioned by @Brian, your code does work on GCC 4.9.
I found that on GCC 4.8 you can make it work by wrapping the expansion in brackets:
const std::size_t rank = (sizeof...(Sizes)); // OK
Upvotes: 2