V K
V K

Reputation: 33

struct assignment with initializer_list in c++

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

Answers (2)

M.M
M.M

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 by T 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

Praetorian
Praetorian

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

Related Questions