大括号的数量如何影响统一初始化

How does the number of braces affect uniform initialization?

本文关键字:影响 初始化 何影响      更新时间:2023-10-16

考虑以下代码片段:

#include <iostream>
struct A {
A() {}
A(const A&) {}
};
struct B {
B(const A&) {}
};
void f(const A&) { std::cout << "A" << std::endl; }
void f(const B&) { std::cout << "B" << std::endl; }
int main() {
A a;
f(   {a}   ); // A
f(  {{a}}  ); // ambiguous
f( {{{a}}} ); // B
f({{{{a}}}}); // no matching function
}

为什么每个调用都会产生相应的输出?大括号的数量如何影响统一初始化?括号省略是如何影响这一切的?

过载解决方案很有趣。

  1. {a}具有用于初始化(临时)const A&参数的精确匹配秩,该秩胜过用户定义的转换B(const A&)作为{a}的实现。该规则是在C++14中添加的,用于解决列表初始化中的歧义(以及对聚合的调整)。

    请注意,概念临时是从未创建:在重载解析选择f(const A&)之后,引用被简单地初始化为引用a,这种解释甚至可以应用于不可复制的类型。

  2. 允许将const A&参数(如上所述)初始化为的构造函数AB,因此调用不明确
  3. 禁止将重复调用复制构造函数(此处为A(const A&))作为多个用户定义的转换,而不是允许每个重载解析级别进行一次这样的转换。因此,在第二种情况下,最外面的大括号必须从{{a}}初始化的A初始化B(允许)。(中间层的大括号可以初始化B,但禁止将其与外层一起复制,并且没有其他方法可以尝试初始化。)
  4. 每一种解释都涉及这样一种被禁止的额外转换

不涉及大括号省略——我们不知道允许它的最外层目标类型。