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

时间:2015-01-29 01:08:02

标签: c++ c++11 std move-semantics

例如,如果我有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,所以我在如何初始化复杂的数据结构方面有点受限。

1 个答案:

答案 0 :(得分:4)

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

  

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

没有任何容器另有说明(据我所知)。

从它的声音来看,你实际上是在移动元素。但是,对于这些,基于MoveConstructibleMoveAssignable的含义的定义适用相当类似的限制(来自第17.6.3.1节[utility.arg.requirements]; rv是任一参数移动constructino或移动赋值):

  

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