当访问 unique_ptr->get_id() 时,这会导致分段错误,因为 release() 是预先运行的。
这里不保证顺序吗?
#include <iostream>
#include <memory>
#include <unordered_map>
class D
{
private:
int id_;
public:
D(int id) : id_{id} { std::cout << "D::D\n"; }
~D() { std::cout << "D::~D\n"; }
int get_id() { return id_; }
void bar() { std::cout << "D::bar\n"; }
};
int main() {
std::unordered_map<int, D*> obj_map;
auto uniq_ptr = std::make_unique<D>(123);
obj_map[uniq_ptr->get_id()] = uniq_ptr.release();
obj_map.at(123)->bar();
return 0;
}
Run Code Online (Sandbox Code Playgroud)
Nat*_*ica 15
这是因为[expr.ass]/1指出:
[...] 在所有情况下,赋值都是在右操作数和左操作数的值计算之后、赋值表达式的值计算之前进行排序的。右操作数排在左操作数之前。对于不确定顺序的函数调用,复合赋值操作是一次计算。
强调我的
根据上面的内容,首先评估右侧,然后评估左侧,然后进行分配。应该注意的是,这仅从 C++17 开始得到保证。在 C++17 之前,未指定左侧和右侧计算的顺序。
Jon*_* S. 13
实际上可以保证这段代码总是会失败。
根据cppreference:
- 在每个简单赋值表达式 E1=E2 和每个复合赋值表达式 E1@=E2 中,E2 的每个值计算和副作用都在 E1 的每个值计算和副作用之前排序 (C++17 起)
换句话说:在您的情况下release()
保证会在之前被调用get_id()
。