Home > Back-end >  What is the rule for type deduction for assignment using brace initialization?
What is the rule for type deduction for assignment using brace initialization?

Time:12-27

In the following code, to my surprise, the { } appears to create a default initialized instance of int rather than of A.

struct A {
  int i = 1;
  A() = default;
  A& operator=(const A& a) {
    this->i = a.i;
    return *this;
  }
  A& operator=(int i) {
    this->i = i;
    return *this;
  }
};

int main() {
  A a;
  a = { };
  return a.i;
}

What rule is used to parse a = { }? I thought that a = { } would have to be equivalent to a = decltype(a){ }.

What is the right term for the type of initialization that takes place here?

Here's an example on godbolt. At -O0 the assembly shows exactly which function is being used. Unless the int assignment operator is removed, A::operator=(int) is called.

CodePudding user response:

Firstly, the braced-init-list {} could be used to initialize both int and A, which are also considered as conversion, and the conversion from {} to int wins in overload resolution, since the conversion from {} to A (via A::A()) is considered as a user-defined conversion.

Assignment operator is not special, compliers just collect all the viable operator=s in overload set, then determine which one should be selected by overload resolution. If you add another operator=(float) you'll get an ambiguous error since conversion from {} to int and from {} to float are both considered as standard conversion with same rank, which wins against user-defined conversion.

  • Related