目前,我试图绕过C ++ 11的统一初始化。我遇到了这种模棱两可的情况:考虑一个可以从两个参数的构造函数或任意长度的初始化列表构造的类:
class Foo {
public:
Foo(int a, int b) {
std::cout << "constructor 1" << std::endl;
}
Foo(std::initializer_list<int>) {
std::cout << "constructor 2" << std::endl;
}
};
遵循统一的初始化约定,我希望以下工作正常:
Foo a (1, 2)
印刷品constructor 1
(duh)
Foo b {1, 2}
版画 constructor 1
Foo c = {1, 2}
版画 constructor 2
但是,似乎编译器将其解释Foo b {1, 2}
为列表初始化,然后调用构造函数2。()
当存在initializer-list构造函数时,该语法是否是强制编译器考虑其他类型的构造函数的唯一方法?
似乎编译器将Foo b {1,2}解释为列表初始化,并调用构造函数2。()语法是否是存在Initializer-list构造函数时迫使编译器考虑其他类型构造函数的唯一方法?
标准草案的引言很好地解释了这一点:
9.4.5.2 [dcl.init.list](强调我的):
如果构造函数的第一个参数的类型为std ::: initializer_list或对某些类型E的cv std :: initializer_list的引用,则构造函数为Initializer-list构造函数,并且没有其他参数或所有其他参数都具有默认值参数([dcl.fct.default])。
[注2:在列表初始化([over.match.list])中,Initializer-list构造函数优于其他构造函数。将初始化程序列表作为参数传递给类C的构造函数模板模板C(T)不会创建初始化程序列表构造函数,因为初始化程序列表参数会使对应的参数成为非推导上下文([temp.deduct 。呼叫])。—尾注]
当非聚合类类型T的对象被列表初始化,从而[dcl.init.list]指定根据本小节中的规则执行重载解析时,或者根据[over.ics]形成列表初始化序列时。列表],重载解析分两个阶段选择构造函数:
如果初始值设定项列表不为空或T没有默认构造函数,则首先执行重载解析,其中候选函数为类T的初始值设定项列表构造函数([dcl.init.list]),并且参数列表由初始值设定项组成列出为单个参数。
否则,或者如果找不到可行的initializer-list构造函数,则再次执行重载解析,其中候选函数是T类的所有构造函数,而参数列表由Initializer列表的元素组成。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句