The constexpr
constructor mentioned by OP is the default constructor that creats an empty list. The actual usable constructor doesn't have any standard interface to begin with.
One primary requirement of constant expressions is that every invoked function is visible, inlined and sepcified as constexpr
. As a result, std::initializer_list
just cannot be constexpr
. It looked like a necessary abomination when C++11 was about to be completed. I wished it were deprecated by now. I can not imagine any use case without alternatives. Usage as function/constructor argument can be handled with std::span<const T>
it just requires a bit more typing:
constexpr auto foo(std::span<std::uint64_t> arr){
return std::ranges::fold_left(arr,0ull,std::plus<>{});
};
auto constexpr N = foo(std::array{1ull, 2, 3});
Other usages are just duplicates of std::array
:
constexpr std::array nnn = {
"this"sv, "sentence", "is", "not", "a", "sentence",
"this", "sentence", "is", "a", "hoax"
};//fixed-size array of std::string_views
As of C++23, all std containers have range constructors, So it's just possible to pass in a std::array
:
std::vector<int> vec(std::from_range, std::array{1,2,3,4});
IMO, std::initializer_list
has no more practical use cases. Everything already has a better substitution.
std::initializer_list
which cannot be used in a constant expression. Sorry, I don't have right now the precise statements from the standard (but the compiler are quite explicit about that :) ). I think it might be the lack of a constexpr copy/move constructor (nn
deduced asstd::initializer_list
and copy/move constructed from the right hand side)