问题描述
考虑代码
#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
output),那么初始化器构造函数会执行(第二个 initializer_list ctor
输出)。我的问题是为什么这是发生?是不是标准构造函数 Foo(int)
更好的匹配?也就是说,我希望这个片段的输出只是 ctor
。
As far as I understand, the value 10
is implicitly converted to a Foo
(first ctor
output), then the initializer constructor kicks in (second initializer_list ctor
output). My question is why is this happening? Isn't the standard constructor Foo(int)
a better match? I.e., I would have expected the output of this snippet to be just ctor
.
PS:如果我标记构造函数 Foo(int)
as explicit
,然后 Foo(int)
是唯一被调用的构造函数,因为 10
现在不能隐式转换为 Foo
。
PS: If I mark the constructor Foo(int)
as explicit
, then Foo(int)
is the only constructor invoked, as the integer 10
cannot now be implicitly converted to a Foo
.
推荐答案
§13.3.1.7[over.match.list] / p1:
§13.3.1.7 [over.match.list]/p1:
当非聚合类类型 T
的对象列表初始化为
(8.5.4)时,重载解析选择构造函数两个阶段:
- 最初,候选函数是类
的初始化列表构造函数(8.5.4)
- 如果没有找到可行的初始化列表构造函数,重载分辨率为再次执行,其中候选函数都是
类T
的构造函数,参数列表由
初始化器列表的元素组成。 / li>
- Initially, the candidate functions are the initializer-list constructors (8.5.4) of the class
T
and the argument list consists of the initializer list as a single argument. - If no viable initializer-list constructor is found, overload resolution is performed again, where the candidate functions are all the constructors of the class
T
and the argument list consists of the elements of the initializer list.
如果初始化器列表没有元素,并且 T
b构造函数,第一阶段被省略。在复制列表初始化中,
如果选择显式
构造函数,则初始化为
形式。
If the initializer list has no elements and T
has a default constructor, the first phase is omitted. In copy-list-initialization, if an explicit
constructor is chosen, the initialization is ill-formed.
只要有一个可行的初始化列表构造函数,当使用列表初始化时,它将占用所有非初始化列表构造函数,并且初始化列表至少一个元素。
As long as there is a viable initializer-list constructor, it will trump all non-initializer-list constructors when list-initialization is used and the initializer list has at least one element.
这篇关于为什么initializer_list构造函数在这里首选?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!