iouvxz iouvxz - 1 month ago 6
C++ Question

What does it mean when I assign {} to an already exsiting object?

#include <vector>
#include <queue>
using namespace std;
int main()
{
vector<priority_queue<int>> vec;
vec.push_back({});//compiles
vec.push_back({1});//don't work
vec[0] = {};//compiles
vec[0] = {1};//don't work
return 0;
}


priority_queue doesn't have a initializer list constructor .

But I can still assign a {} to it .

I think it means that I just constructed an empty priority_queue using the default constructor,and assigned it to the already exsiting priority_queue object .

But shouldn't that be something like this ?

vec[0] = priority_queue<int>{};//compiles
vec[0] = priority_queue<int>();//compiles


What does this acctuly mean ?And why does it work ?
I just omitted the priority_queue part .

vec[0] = {};//compiles
vec[0] = ();//don't work


That dosen't mean I can reinitialize my queue object at any time ,dose it ?

priority_queue<int> que{};
que = {};//compiles
que{};//don't work


Is {} here something like nullptr ?

{} is an empty object for everything like nullptr is an empty pointer for every kind of pointers ?

priority_queue<int>* p{};
p = nullptr;
p = {};// still works

AnT AnT
Answer

Assignment operator (including compound assignment) is given special treatment in C++11, since it is included into the list of contexts where list-initialization is allowed to occur. Because of that special treatment a plain { ... } initializer is allowed on the right-hand side of assignment operator, as in your

vec[0] = {};

And, according to the specification of assignment operator, it is interpreted as

vec[0].operator =({});

In this case {} is used as an initializer for an argument in function call. Since the object being initialized is not an aggregate, the contents of {} is interpreted as argument list for regular constructors. Since the list is empty it results in default constructor being selected.

This special treatment does not extend to other operators

struct S
{
  S(int, int, int) {}
  S &operator +=(const S& rhs) { return *this; }
  S operator +(const S& rhs) const { return *this; }
};

int main()
{
  S s(1, 2, 3);
  s = { 4, 5, 6 };  // OK - special treatment for `=`
  s += { 4, 5, 6 }; // OK - special treatment for `+=`
  s + { 4, 5, 6 };  // Error - no special treatment for `+`
  s + S{ 4, 5, 6 }; // OK, constructing the object explicitly works
}
Comments