其他分享
首页 > 其他分享> > c – List-initializer和variadic构造函数

c – List-initializer和variadic构造函数

作者:互联网

CPP reference开始列表初始化:

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)

因此首先考虑使用initializer_list的构造函数.如果做不到这一点,列表的每个元素都被视为构造函数的参数.然而

#include <iostream>

using namespace std;

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

int main(){

    A a = {2,3,4};

}

输出为3,表示Args …解包为int,int,int.为什么Args …不仅仅是单数化的initializer_list< int>,list-initialisation指出的细节是第一个尝试类型的构造函数?

解决方法:

[temp.deduct.call]/1 Template argument deduction is done by comparing each function template parameter type (call it P) with the type of the corresponding argument of the call (call it A) as described below. If removing references and cv-qualifiers from P gives std::initializer_list<P'> for some P' and the argument is an initializer list (8.5.4), then deduction is performed instead for each element of the initializer list, taking P' as a function template parameter type and the initializer element as its argument. Otherwise, an initializer list argument causes the parameter to be considered a non-deduced context (14.8.2.5).

强调我的.因此,从类型为initializer_list< int>的参数中对构造函数进行模板参数推导.失败.

标签:variadic,c,c11,templates,initializer-list
来源: https://codeday.me/bug/20190829/1761792.html