jeudi 26 novembre 2015

List-initializer and variadic constructor

From CPP reference on list-initialisation:

Otherwise, the constructors of T are considered, in two phases:

  • All constructors that take std::initializer_list as the only argument, or as the first argument if the remaining arguments have default values, are examined, and matched by overload resolution against a single argument of type std::initializer_list

  • If the previous stage does not produce a match, all constructors of T participate in overload resolution against the set of arguments that consists of the elements of the braced-init-list, with the restriction that only non-narrowing conversions are allowed. If this stage produces an explicit constructor as the best match for a copy-list-initialization, compilation fails (note, in simple copy-initialization, explicit constructors are not considered at all)

So a constructor using initializer_list is considered first. Failing that, each element of the list is considered as arguments for constructors. However

#include <iostream>

using namespace std;

struct A{
    template <typename... Args> A(Args... li) { cout << sizeof...(Args) << endl;}
};

int main(){

    A a = {2,3,4};

}

The output is 3 which indicates that Args... unpacks as int, int, int. Why is it that Args... was not simply made the singular initializer_list<int>, which the details on list-initialisation indicated would be the first attempted type of constructor?

Aucun commentaire:

Enregistrer un commentaire