How does the number of braces affect uniform initialization?

不打扰是莪最后的温柔 提交于 2019-12-20 08:40:59

问题


Consider the following code snippet:

#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
}

Why does each call fabricate the corresponding output? How does the number of braces affect uniform initialization? And how does brace elision affect all this?


回答1:


Overload resolution is fun like this.

  1. {a} has exact match rank for initializing (a temporary for) the const A& parameter, which outcompetes the user-defined conversion B(const A&) as a realization of {a}. This rule was added in C++14 to resolve ambiguities in list-initialization (along with adjustments for aggregates).

    Note that the notional temporary is never created: after overload resolution picks f(const A&), the reference is simply initialized to refer to a, and this interpretation can apply even for non-copyable types.

  2. It would be permissible to initialize a const A& parameter (as above) to the constructor for either A or B, so the call is ambiguous.
  3. Calling a copy constructor (here, A(const A&)) repeatedly is prohibited as multiple user-defined conversions—rather than allowing one such conversion per level of overload resolution. So the outermost braces must initialize a B from the A initialized from {{a}} as (permitted) in the second case. (The middle layer of braces could initialize a B, but copying it with the outer layer would be prohibited and there’s nothing else to try to initialize.)
  4. Every interpretation involves such a disallowed extra conversion.

No brace elision is involved—we don’t know the outermost target type to allow it.



来源:https://stackoverflow.com/questions/54504463/how-does-the-number-of-braces-affect-uniform-initialization

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!