Pass constexpr intializer_list as an argument in C ++ 14

Why this does not work:

constexpr initializer_list<int> ilist = {1,2,3,4}; constexpr int my_min = min(ilist); 

While doing this:

 constexpr int my_min = min({1,2,3,4}); 

I base my code on the constexpr std :: min () function, as shown here , and I use clang3.5.0 for the compiler (g ++ 4.9.1 does not seem to know about constexpr std :: min ()).

I can not understand the error I am getting:

 clang35 -stdlib=libc++ -std=c++14 test.cpp -o test; test.cpp:158:35: error: constexpr variable 'ilist' must be initialized by a constant expression constexpr initializer_list<int> ilist = {1,2,3,4}; ^ ~~~~~~~~~ test.cpp:158:35: note: pointer to subobject of temporary is not a constant expression test.cpp:158:43: note: temporary created here constexpr initializer_list<int> ilist = {1,2,3,4}; ^ test.cpp:159:17: error: constexpr variable 'my_min' must be initialized by a constant expression constexpr int my_min = min(ilist); ^ ~~~~~~~~~~ test.cpp:159:30: note: initializer of 'ilist' is not a constant expression constexpr int my_min = min(ilist); ^ test.cpp:159:30: note: in call to 'initializer_list(ilist)' test.cpp:158:35: note: declared here constexpr initializer_list<int> ilist = {1,2,3,4}; 
+6
source share
2 answers

The reason your first fragment is not compiled, and not the second, is the point in time at which the base array is created. [Dcl.init.list] / 5:

An object of type std::initializer_list<E> built from the initializer, as if the implementation allocated a temporary array of N elements of type const E , where N is the number of elements in the list of initializers.

Now, when calling min we turn to the elements of this array. However, [expr.const] / 7 is inviolable:

enter image description here

None of the exceptions apply, but pay attention to the last marker point, which is applicable in your second example.

Clang (unsurprisingly) is correct, and GCC mistakenly accepts your code. The above solution also explains why @dyp code crashes: Performing ltr to i conversion is not a constant expression. In particular, (2.7.1) does not apply, since the temporary is not const .

+2
source

C ++ 14 is not fully implemented in either g ++ or clang ++. In your specific case: g ++ STL did not implement template constexpr T min(std::initializer_list ilist); while clang ++ does not yet have a constexptr constructor for initializer_list.

-2
source

Source: https://habr.com/ru/post/980670/


All Articles