Like static_assert so that the list of initializers is of a certain size

Is it possible to verify that the list of initializers passed to the constexpr constructor is a specific size? Or could this be done only at runtime?

This is an idea, but it does not work:

 struct group { constexpr group( std::initializer_list<std::initializer_list<UINT const> const> groups ) { static_assert(each_list_size_greater_than_1(groups.begin(), groups.end())); } constexpr static bool each_list_size_greater_than_1( std::initializer_list<std::initializer_list<UINT const> const>::const_iterator const begin , std::initializer_list<std::initializer_list<UINT const> const>::const_iterator const end) { return begin == end || begin->size() > 1 && each_list_size_greater_than_1(begin + 1, end); } }; 

I reviewed the implementation of VS2015 std::initializer_list , and begin() , end() and size() are all constexpr functions.

+7
c ++ c ++ 11 visual-studio-2015
source share
1 answer

Although size() for std::initializer_list<T> can be evaluated as constexpr , the size() member will not behave like a constexpr inside the constexpr function: intentionally, the objects behave like constexpr in the constexpr expression where they were entered, but not elsewhere.

For example:

 constexpr get_size(std::initializer_list<int> list) { constexpr std::size_t csize = list.size(); // ERROR (1) std::size_t size = list.size(); // OK return size; } int main() { constexpr std::size_t csize = get_size(std::initializer_list<int>{ 1, 2, 3 }); // OK (2) // ... } 

In the first case (1), the value assumed to be equal to a constexpr depends on the data created before the start of constexpr . As a result, he does not evaluate a constexpr . In the second case (2), the data is defined within constexpr , and thus, the result can become constexpr .

I did not participate in discussions leading to this design, but it seems to be motivated by the desire to prevent constexpr arguments that change the type of the result of the constexpr function: if the values โ€‹โ€‹were constexpr inside the function definition, they would also be constexpr in the return value and could thus used as template arguments in the return type. This will lead to different values โ€‹โ€‹for the constexpr function giving different types. Until now, you can get a different return type only by changing the types of the arguments to the function and / or by changing the number of arguments to the function.

+9
source share

All Articles