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 itA
) as described below. If removing references and cv-qualifiers fromP
givesstd::initializer_list<P'>
for someP'
and the argument is an initializer list (8.5.4), then deduction is performed instead for each element of the initializer list, takingP'
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