#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
答案 0 :(得分:4)
赋值运算符(包括复合赋值)在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
}
答案 1 :(得分:2)
大括号({}
)通常用于初始化对象,而不仅仅是初始化列表。因此,没有初始化列表的类仍然可以使用大括号来初始化对象,例如
class A {
public:
A(int i);
}
A a{5}; // Invokes A's constructor
它也可以用于aggregate initialization(例如,初始化结构数据成员。)在您的情况下,它调用priority_queue
的默认构造函数。