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.