Reputation: 33
I have a struct
struct Data {
int a,b;
Data& operator=(Data &&other) = delete;
};
Now when I call the assignment operator
Data A[2];
A[0] = {1, 2};
I get a compile error for calling a deleted function.
My question is how does the initializer_list gets converted to a rvalue reference of type Data
?
Upvotes: 3
Views: 2233
Reputation: 141586
This syntax is covered by C++17 [expr.ass]/9:
A braced-init-list may appear on the right-hand side of
- [...]
- an assignment to an object of class type, in which case the initializer list is passed as the argument to the assignment operator function selected by overload resolution.
with an example given:
z = { 1,2 }; // meaning z.operator=({1,2})
The behaviour of giving a braced-init-list as argument to a function means that the function parameter is initialized by that list. In this case Data&& other
is initialized by {1, 2}
. This is covered by [dcl.init.list]/3.4:
Otherwise, if
T
is a reference type, a prvalue of the type referenced byT
is generated. The prvalue initializes its result object by copy-list-initialization or direct-list-initialization, depending on the kind of initialization for the reference. The prvalue is then used to direct-initialize the reference.
So there is a prvalue of type Data
initialized by {1, 2}
which becomes the initializer for the parameter of operator=
.
Upvotes: 3
Reputation: 109119
My question is how does the initializer_list gets converted to a rvalue reference of type Data?
If by initializer_list you mean the type std::initializer_list
, there isn't one in your example. You're using list initialization to create a temporary Data
instance (a prvalue, not an rvalue reference) and assigning it to A[0]
, which of course will fail since the move assignment operator is deleted.
Your example is identical to
A[0] = Data{1, 2};
Upvotes: 3