考虑代码
#include <iostream>
class Foo
{
int val_;
public:
Foo(std::initializer_list<Foo> il)
{
std::cout << "initializer_list ctor" << std::endl;
}
/* explicit */ Foo(int val): val_(val)
{
std::cout << "ctor" << std::endl;
};
};
int main(int argc, char const *argv[])
{
// why is the initializer_list ctor invoked?
Foo foo {10};
}
输出是
ctor
initializer_list ctor
据我了解,该值10
隐式转换为Foo
(第一个ctor
输出),然后初始化构造函数插入(第二个initializer_list ctor
输出)。我的问题是为什么会这样?标准构造函数Foo(int)
不是更好的选择吗?即,我希望该代码段的输出为just ctor
。
PS:如果我将构造函数标记Foo(int)
为explicit
,则Foo(int)
是唯一调用的构造函数,因为10
现在无法将整数隐式转换为Foo
。
§13.3.1.7[over.match.list] / p1:
当非聚合类类型的对象
T
被列表初始化(8.5.4)时,重载解析会分两个阶段选择构造函数:
- 最初,候选函数是该类的初始化器列表构造函数(8.5.4),
T
并且参数列表由作为单个参数的初始化器列表组成。- 如果找不到可行的初始化程序列表构造函数,则再次执行重载解析,其中候选函数是该类的所有构造函数,
T
并且参数列表由初始化程序列表的元素组成。如果初始化列表没有元素,并且
T
具有默认构造函数,则省略第一阶段。在复制列表初始化中,如果explicit
选择了构造函数,则初始化格式不正确。
只要有可行的initializer-list构造函数,当使用list-initialization并且initializer列表包含至少一个元素时,它将胜过所有非initializer-list构造函数。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句