c.AddString({ {"1",1}, {"2", 2}, {"3", 3} });
You're passing a braced-init-list, which itself contains nested brace-init-lists to AddString
. The argument can match the std::initializer_list<std::pair<const char*,int>>
parameter if the inner braced-init-lists can be converted to std::pair<const char*,int>
.
This process of overload resolution occurs in two steps; first an attempt is made to match constructors of std::pair
that take an std::initializer_list
argument. Since std::pair
has no such constructor, the second step occurs, where the other constructors of std::pair<const char*,int>
are enumerated with char const[2]
and int
as the arguments. This will match the following pair
constructor because char const[2]
is implicitly convertible to char const *
and the constructor itself is not explicit
.
template< class U1, class U2 >
constexpr pair( U1&& x, U2&& y );
Quoting N3337 §13.3.1.7/1 [over.match.list]
When objects of non-aggregate class type T
are list-initialized (8.5.4), overload resolution selects the constructor in two phases:
— Initially, the candidate functions are the initializer-list constructors (8.5.4) of the class T
and the argument list consists of the initializer list as a single argument.
— If no viable initializer-list constructor is found, overload resolution is performed again, where the candidate functions are all the constructors of the class T
and the argument list consists of the elements of the initializer list.
If the initializer list has no elements and T
has a default constructor, the first phase is omitted. In copy-list-initialization, if an explicit
constructor is chosen, the initialization is ill-formed.