Why is std::initializer_list<_E>::size
not allowable in a static_assert
, even though it's declared as a constexpr
in my libstdc++ (v. 4.6)?
For example, the following code:
template<class T, int Length>
class Point
{
public:
Point(std::initializer_list<T> init)
{
static_assert(init.size() == Length, "Wrong number of dimensions");
}
};
int main()
{
Point<int, 3> q({1,2,3});
return 0;
}
gives the following error:
test.C: In constructor ‘Point<T, Length>::Point(std::initializer_list<_Tp>) [with T = int, int Length = 3]’:
test.C:60:26: instantiated from here
test.C:54:7: error: non-constant condition for static assertion
test.C:54:73: in constexpr expansion of ‘init.std::initializer_list<_E>::size [with _E = int, std::initializer_list<_E>::size_type = long unsigned int]()’
test.C:54:7: error: ‘init’ is not a constant expression
Note that this works just fine for a trivial example:
class A
{
public:
constexpr int size() { return 5; }
};
int main()
{
A a;
static_assert(a.size() == 4, "oh no!");
return 0;
}
size()
is declared asconstexpr
in libstdc++, but it should be noted that the Standard does not require this. So even if you got this to work (e.g. perhaps using Evgeny Panasyuk's approach below), you couldn't rely on this to work with other implementations of the Standard Library. – Abbasize()
,begin()
andend()
are all declared asconstexpr
in the C++14 proposal. – Abba