Consider the code
#include <iostream>
class Foo
{
int val_;
public:
Foo(std::initializer_list<Foo> il)
{
std::cout << "initializer_list ctor" << std::endl;
}
/* explicit */ Foo(int val): val_(val)
{
std::cout << "ctor" << std::endl;
};
};
int main(int argc, char const *argv[])
{
// why is the initializer_list ctor invoked?
Foo foo {10};
}
The output is
ctor
initializer_list ctor
As far as I understand, the value 10
is implicitly converted to a Foo
(first ctor
output), then the initializer constructor kicks in (second initializer_list ctor
output). My question is why is this happening? Isn't the standard constructor Foo(int)
a better match? I.e., I would have expected the output of this snippet to be just ctor
.
PS: If I mark the constructor Foo(int)
as explicit
, then Foo(int)
is the only constructor invoked, as the integer 10
cannot now be implicitly converted to a Foo
.
§13.3.1.7 [over.match.list]/p1:
As long as there is a viable initializer-list constructor, it will trump all non-initializer-list constructors when list-initialization is used and the initializer list has at least one element.