Unexpected mutable std :: initializer_list

I twisted the index trick a bit to see what I could go with, and came across a strange mistake ... First, simple non-old indexes:

template<std::size_t...> struct indices {}; template<std::size_t N, std::size_t... Indices> struct make_indices: make_indices<N-1, N-1, Indices...> {}; template<std::size_t... Indices> struct make_indices<0, Indices...>: indices<Indices...> {}; 

I created a compile-time array class derived from std::initializer_list and had it indexed (suppose that N3471 is support for your compiler. In any case, it will be in the following standard). There he is:

 template<typename T> struct array: public std::initializer_list<T> { constexpr array(std::initializer_list<T> values): std::initializer_list<T>(values) {} constexpr auto operator[](std::size_t n) -> T { return this->begin()[n]; } }; 

So, I tried to create a function that returns a copy of array after adding 1 to each of its members:

 template<typename T, std::size_t... I> auto constexpr add_one(const array<T>& a, indices<I...>) -> const array<T> { return { (a[I]+1)... }; } 

And to finish with the code, here is my main one:

 int main() { constexpr array<int> a = { 1, 2, 3 }; constexpr auto b = add_one(a, make_indices<a.size()>()); return 0; } 

I did not think that the code would compile anyway, but I am very surprised by the error message (here is the ideone code):

 In function 'int main()': error: 'const smath::array<int>{std::initializer_list<int>{((const int*)(& const int [3]{2, 3, 4})), 3u}}' is not a constant expression 

So, can someone explain to me what is definitely not enough for the compiler in the above code?

EDIT: Follow-up on this

  • Is constexpr std :: initializer_list object declaration legal?
  • Confusion over constant expression
+7
c ++ c ++ 11 initializer-list compile-time variadic-templates
Apr 15 '13 at 19:27
source share
1 answer

From: man himself http://www.stroustrup.com/sac10-constexpr.pdf

In particular: ? its return type and the types of its parameters (if any) are literal types (see x2.2). For concreteness, literal types include bool, int, or double; ? his body is a compound formulation of the form {return expr; } where expr is such that if arbitrary constant expressions of the corresponding types are replaced by parameters in expr, then the resulting expression is a constant expression, as defined in the opening paragraph x2. The expression expr is called a potential constant expression.

0
Jun 14 '13 at 0:22
source share



All Articles