c – 为什么使用支撑初始化列表时首选std :: initializer_list构造函数?
作者:互联网
考虑一下代码
#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)不是更好的匹配吗?即,我本来希望这个片段的输出只是ctor.
PS:如果我将构造函数Foo(int)标记为显式,则Foo(int)是唯一被调用的构造函数,因为整数10现在不能隐式转换为Foo.
解决方法:
§13.3.1.7[over.match.list] / p1:
When objects of non-aggregate class type
T
are list-initialized
(8.5.4), overload resolution selects the constructor in two phases:
- 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 classT
and the argument list consists of
the elements of the initializer list.If the initializer list has no elements and
T
has a default
constructor, the first phase is omitted. In copy-list-initialization,
if anexplicit
constructor is chosen, the initialization is
ill-formed.
只要有一个可行的初始化列表构造函数,当使用列表初始化并且初始化列表至少有一个元素时,它将胜过所有非初始化列表构造函数.
标签:c,c11,language-lawyer,constructor,initializer-list 来源: https://codeday.me/bug/20190928/1827555.html