Reputation: 1720
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})
?
Upvotes: 5
Views: 405
Reputation: 49028
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.
Upvotes: 8