首页 > 解决方案 > 这个 C++ 代码会一直按我的预期工作,还是不能保证执行顺序?

问题描述

好的,我有一些似乎可以工作的代码,但我不确定它是否会一直工作。我正在使用类的成员之一作为映射键将 unique_ptr 移动到 stl 映射中,但我不确定在某些情况下移动是否会使指针无效。

代码如下:

struct a
{
    std::string s;
};
std::map<std::string, std::unique_ptr<a>> m;
std::unique_ptr<a> p = std::make_unique<a>();

// some code that does stuff

m[p->s] = std::move(p);

所以这目前似乎可行,但在我看来,在将字符串用作映射键之前 p 可能会变得无效,这会导致内存异常。显然,我可以在移动之前创建一个临时字符串,或者我可以通过迭代器进行分配,但如果没有必要,我不希望这样做。

标签: c++order-of-execution

解决方案


此代码具有明确定义的行为。

在 C++17 中,std::move(p)将在m[p->s]. 在 C++17 之前,std::move(p)可以在m[p->s]. 但是,这并不重要,因为std::move(p)不会修改p. 只有实际导致p被移出的分配。

被调用的赋值运算符具有签名

unique_ptr& operator=(unique_ptr&& other);

并被称为

m[p->s].operator=(std::move(p));

这意味着在输入的主体之前p,保证不会发生修改(参数的初始化只是一个引用绑定)。当然,在评估对象表达式之前,无法输入的主体。operator=otheroperator=m[p->s]

因此,您的代码在所有版本的 C++ 中都定义良好。


推荐阅读