I have following template function:
template<typename T> void foo2(T t) {}
I know that I cannot call it using:
foo2({1,2,3});
because initializer list is a non deduced context for a template argument. I have to use:
foo2<std::initializer_list<int>>({1,2,3});
but I can also use:
foo2(std::initializer_list<int>({1,2,3}));
which makes me wonder what is the difference between: {1,2,3}
and std::initializer_list<int>({1,2,3})
?
An object of type std::initializer_list<T> is a lightweight proxy object that provides access to an array of objects of type const T .
initializer_list constructorsThe initializer_list Class represents a list of objects of a specified type that can be used in a constructor, and in other contexts. You can construct an initializer_list by using brace initialization: C++ Copy. initializer_list<int> int_list{5, 6, 7}; Important.
A braced-init list isn't an expression, and thus doesn't have a type. When you call
foo2({1,2,3});
the compiler doesn't know what type {1,2,3}
represents in your mind, and so it doesn't compile.
foo2<std::initializer_list<int>>({1,2,3});
compiles because here the compiler doesn't have to deduce the type, you have specified it, it is std::initializer_list<int>
. So it can initialize t
with {1,2,3}
.
The third call also compiles because the compiler can deduce the type. std::initializer_list<int>({1,2,3})
is obviously a std::initializer_list<int>
, and so it can initialize t
with the passed prvalue.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With