c++ - 这个 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++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=
other
operator=
m[p->s]
因此,您的代码在所有版本的 C++ 中都定义良好。
推荐阅读
- javascript - React - 从 Firebase 检索和打印数据
- vba - 如何在 Word VBA 中退出多个子
- string - 使用 MATLAB 脚本简化字符串
- c++ - 从函数返回一个数组供以后使用
- kubernetes - Istio环境下无法连接mysql
- spring - 允许 Spring REST 方法调用异步方法而不等待响应
- javascript - 如何使用 JQuery 以不同方式单击一个按钮激活 2 个 div?
- ibm-cloud - 日志没有进入 logDNA 控制台
- html - 使用 XSLT 将 HTML 转换为 XML 以使用 SSIS 进行处理
- ios - SwiftUI 中自定义 UIViewRepresentable UITextView 的框架高度问题