考虑代码
#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
(first ctor
输出),然后初始化构造函数启动(第二个initializer_list ctor
输出)。我的问题是为什么会发生这种情况?不是标准构造函数吗Foo(int)
更好的匹配?也就是说,我预计这个片段的输出只是ctor
.
PS:如果我标记构造函数Foo(int)
as explicit
, then Foo(int)
是唯一被调用的构造函数,作为整数10
现在不能隐式转换为Foo
.
§13.3.1.7 [over.match.list]/p1:
当非聚合类类型的对象T
是列表初始化的
(8.5.4),重载决策分两个阶段选择构造函数:
- 最初,候选函数是类的初始化列表构造函数(8.5.4)
T
参数列表包括
初始化列表作为单个参数。
- 如果没有找到可行的初始化列表构造函数,则再次执行重载决策,其中候选函数全部为
类的构造函数
T
参数列表包括
初始化列表的元素。
如果初始值设定项列表没有元素并且T
有一个默认值
构造函数,第一阶段被省略。在复制列表初始化中,
如果explicit
选择构造函数,初始化是
格式不正确。
只要有一个可行的初始化列表构造函数,当使用列表初始化并且初始化列表至少有一个元素时,它就会胜过所有非初始化列表构造函数。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)