C++11:使用 std::move 只对临时对象安全吗?

C++11: Is using std::move only safe on temporary objects?

在我的代码中,我有这样的东西:

unordered_multimap<string, unordered_map<string, string> > mEntities;
...
vector<unordered_map<string, string> > rawEntities;
if (qi::phrase_parse(&buf[0], (&buf[0]) + buf.size(), EntityParser<char*>(), qi::space, rawEntities)) {
    for (auto &propGroup : rawEntities) {
        auto search = propGroup.find("classname");
        if (search != propGroup.end()) {
            // is stealing propGroup safe???
            mEntities.emplace(search->second, std::move(propGroup)); 
        }
    }
}
// rawEntities goes out of scope here

如您所见,我在推导出 unordered_map<string, string>& 类型的对象上使用 std::move,这显然不是 unordered_map<string, string>&&。不过,我确信因为 rawEntitiesfor 循环之后超出范围,它的元素(字符串->字符串映射)将永远不会被再次使用。所以我认为窃取(移动)它的元素数据是安全的,因为它们不会被再次使用。

当我运行程序时,它似乎可以工作。但这种不好的做法/反模式,特别是标准是否保证它是安全的?

恰恰相反。在临时对象上使用 std::move 是没有意义的。它们已经是 R 值,并且在传递给函数时将被推断为 R 值引用。 std::move 的重点是将 L 值转换为 R 值引用,以便它们可以从中移动。

So I'm figuring that it's safe to steal (move) its elements data because they won't be used again.

是的,这是正确的。

一般来说,临时对象是未命名的并且已经是右值std::move 并不适用,因为它未命名。

std::move什么时候适用?每当对象将要过期并且不再需要时。这就是 std::move 所做的,它投射值类别以便可以从中移动。

这是一个有趣的用例 - 窃取容器的(过滤后的)内容,而不仅仅是整个容器。

鉴于 vector 的内容在 for 循环完成后将不再需要,那么是的,它将按预期工作