在 std::move 之后重复使用 std 容器是否安全

Is it safe to reuse a std container after std::move?

本文关键字:std 安全 是否 move 之后      更新时间:2023-10-16

例如,如果我有一个std::list,并且我使用std::move()将其信息移动到std::map中,通过填充更多数据来重用列表是否安全,以便我可以向地图添加更多条目?我依稀记得另一位程序员告诉我,std::move()将事物置于未知状态,因此您以后不应该重用它们,但我只想确认一下,因为我似乎无法通过搜索找到任何相关信息。

如果它不安全,那么在移动列表后调用列表中的clear()是否可以重用?

以下是我正在做的事情的一个例子:

// Create the initial list, give it some data, then move it into the map.
typedef std::list<std::pair<string, uint16>> TListType;
TListType data;
data.push_back(std::make_pair("some string", 0));
data.push_back(std::make_pair("some other string", 0));
std::map<uint32, TListType> mappedData;
mappedData.insert(std::make_pair(0, std::move(data)));
// Insert more data into the list, then move into the map as a new entry.
data.push_back(std::make_pair("new strings", 9));
mappedData.insert(std::make_pair(1, std::move(data)));

我必须做所有这些丑陋的混乱的原因是因为我不能使用初始值设定项列表,而且我没有 Boost,所以我在如何初始化复杂的数据结构方面有点限制。

从标准C++库类移动后,它们处于未指定的状态,但在其他方面完全可用。相关部分是 17.6.5.15 [lib.types.movedfrom]:

C++标准库中定义的类型的对象可以从 (12.8) 中移动。移动操作可以显式指定或隐式生成。除非另有说明,否则此类移出对象应 置于有效但未指定的状态。

没有一个容器另有说明(据我所知)。

不过,从它的声音来看,你实际上是在移动元素。但是,对于这些,根据MoveConstructibleMoveAssignable含义的定义,适用相当相似的限制(来自第17.6.3.1节[实用程序.arg.requirements]; rv是移动构造或移动赋值的参数):

rv 的状态未指定 [ 注意:rv仍必须满足使用它的库组件的要求。无论是否已从中移动rv,这些要求中列出的操作都必须按指定工作。 —尾注 ]