【问题标题】:C++11: Is using std::move only safe on temporary objects?C++11:std::move 只对临时对象安全吗?
【发布时间】:2015-11-21 01:59:09
【问题描述】:

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

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

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

【问题讨论】:

  • 只看你的问题标题,答案是临时对象(根据定义)是纯右值,而std::move 只是一个演员表,在这种情况下这是不必要的。

标签: c++ c++11 move lvalue


【解决方案1】:

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

std::move 何时适用?每当对象即将到期并且不再需要时。这就是std::move 所做的,它转换值类别以便可以从中移动它。

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

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

【讨论】:

    【解决方案2】:

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

    所以我认为窃取(移动)其元素数据是安全的 因为它们不会再被使用了。

    是的,这是正确的。

    【讨论】:

      猜你喜欢
      • 2023-02-07
      • 2013-07-16
      • 2016-03-26
      • 1970-01-01
      • 2012-11-17
      • 2020-11-04
      • 2015-01-07
      • 1970-01-01
      相关资源
      最近更新 更多