本文介绍了为什么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 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构造函数在这里首选?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

1403页,肝出来的..

09-06 09:10