【问题标题】:practical r-value references实用的 r 值参考
【发布时间】:2012-05-17 21:34:34
【问题描述】:

我想我可以尝试一下移动语义。所以我抓到了一个很grainy/lowres video of Scott Meyers talking about move semantics,虽然说视频里的代码不可读。

所以我编写了一个包含字符串向量的一次性类。

class ShoppingList
{
private:
    vector<string> m_vsList;
public:
    ...
};

我想知道是否可以使用移动语义将字符串的临时向量移动到成员变量 m_vsList 中?

为此,我可能会编写一个移动函数,例如:

void MoveList( vector<string> && r )
{
    m_vsList = std::move(r);
}

我应该声明我正在 VS2011 beta 编译器上尝试这个。

问题

这是正确的/可能的吗?如果是这样,我如何指定一个临时的vector&lt;string&gt;

例如MoveList( {string("c"), string("b"), string("a")} ) 无效。

我应该限制移动语义来移动构造函数和/或移动赋值重载吗?

如果我 std::move 进入 m_vsList 并且 m_vsList 已经包含数据,那么该数据会发生什么,它会泄漏吗?那么我应该在移动之前明确清除该向量吗?

【问题讨论】:

  • 或者,如果您的编译器还没有初始化列表:MoveList(std::move(my_vector_of_strings));
  • @freefallr : VC11 不支持统一初始化。
  • @KerrekSB 演示的语法。
  • 您可能会考虑使用交换,而不是在向量上使用 std::move。为什么?向量可能有一个做同样事情的 = 运算符,但这种方式更明确。当您收到这样的右值时,您确切地知道自己想要做什么,我会考虑只是这样做,而不是将您想要的东西隐藏在一个相当通用的界面后面。当您因为正在编写模板或其他内容而不知道需要做什么时,请使用通用接口。
  • 虽然如前所述,它可能不是最有用的东西:为什么不直接创建一个函数void set_vsList(std::vector&lt;string&gt; r){m_vsList=std::move(r);},那么您仍然可以在调用端决定是否应该复制参数或移动。

标签: c++ c++11 rvalue-reference move-semantics


【解决方案1】:

是的,这是正确且可能的。请参阅std::map::operator[] (Key&amp;&amp; key) 启用右值的版本。​​

如果你想创建一个临时的测试,一旦你的编译器完全支持初始化列表,上面列出的应该可以工作。现在,您可以创建一个返回 std::vector&lt;std::string&gt; 的函数,或者简单地创建一个非临时向量并使用 std::move

【讨论】:

  • 有谁知道 VS2011 是否会永远支持初始化列表?
  • VS2011 不会,但 VS2012 可能。 MS 说他们计划有一天会实施完整的标准。
  • 我认为移动非临时(左值)变量是一件坏事,除非你绝对确定它永远不会被再次使用。即便如此,这似乎也是一种不好的做法。
  • @freefallr 你首先想要从什么开始?如果不复制或不支持 C++11 初始化,就无法使用有意义的数据初始化未命名向量。
  • @ComicSansMS :当然有——从函数中返回它。
【解决方案2】:

如果您的编译器不支持初始化列表,您可以使用以下方法制作空右值向量:

MoveList(vector<string>());

或非空右值:

vector<string>  lv_vec; 
lv_vec = ...
MoveList(vector<string>(lv_vec));

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2022-07-29
    • 2011-12-07
    • 2021-06-04
    • 1970-01-01
    • 2011-11-11
    • 1970-01-01
    • 1970-01-01
    • 2017-05-11
    相关资源
    最近更新 更多