其他分享
首页 > 其他分享> > c – 为什么使用支撑初始化列表时首选std :: initializer_list构造函数?

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 class T 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 an explicit constructor is chosen, the initialization is
ill-formed.

只要有一个可行的初始化列表构造函数,当使用列表初始化并且初始化列表至少有一个元素时,它将胜过所有非初始化列表构造函数.

标签:c,c11,language-lawyer,constructor,initializer-list
来源: https://codeday.me/bug/20190928/1827555.html