Recently I wrote a very simple class.
class C
{
public:
void AddString(std::initializer_list<std::pair<const char*,int>> x)
{
//irrelevant
}
};
int main()
{
C c;
c.AddString({ {"1",1}, {"2", 2}, {"3", 3} });
.... //other unimportant stuff
return 0;
}
To my pleasant surprise it compiled and worked correctly. Can someone please explain to me how the compiler was able to deduce the nested braced initializers were for a std::pair? I am using MSVS 2013.
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
Tare 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 classTand 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 classTand the argument list consists of the elements of the initializer list.If the initializer list has no elements and
Thas a default constructor, the first phase is omitted. In copy-list-initialization, if anexplicitconstructor is chosen, the initialization is ill-formed.
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