当我将 {} 分配给一个已经存在的对象时,这意味着什么?

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 没有初始化列表构造函数。

但我仍然可以为其分配 {}。

我认为这意味着我只是使用默认构造函数构造了一个空 priority_queue,并将其分配给已经存在的 priority_queue 对象。

但不应该是这样的吗?

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

这究竟是什么意思?它为什么有效? 我只是省略了 priority_queue 部分。

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

这并不意味着我可以随时重新初始化我的队列对象吗?

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

这里的 {} 是 nullptr 之类的东西吗?

{} 对任何事物都是一个空对象 nullptr 对于每一种指针都是一个空指针 ?

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

大括号 ({}) 通常用于对象的初始化,而不仅仅是初始化列表。因此,没有初始化列表的 class 仍然可以使用大括号来初始化对象,例如

class A { 
    public: 
    A(int i);
}

A a{5}; // Invokes A's constructor

它也可以用于 aggregate initialization(例如结构数据成员的初始化。)在你的例子中,它调用了 priority_queue 的默认构造函数。

赋值运算符(包括复合赋值)在 C++11 中得到特殊处理,因为它包含在允许进行列表初始化的上下文列表中。由于这种特殊处理,赋值运算符的右侧允许使用普通的 { ... } 初始值设定项,如您的

vec[0] = {};

并且,根据赋值运算符的规范,解释为

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

在这种情况下,{} 用作函数调用中参数的初始值设定项。由于正在初始化的对象不是聚合,因此 {} 的内容被解释为常规构造函数的参数列表。由于列表为空,因此会选择默认构造函数。

这种特殊待遇不会扩展到其他运营商

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
}