std::move 到函数

std::move to a function

我有这个示例代码:

#include <iostream>

class Struct {
public:
   Struct() { std::cout << "0" << std::endl; }
   Struct(Struct&) { std::cout <<"1"<<std::endl;}
   Struct(const Struct&) { std::cout << "2" << std::endl; }
};

class Struct2 {
public:
    Struct s;

    Struct2() {}
    void setMember(const Struct& aux) { s = aux; }
};

int main()
{
    Struct s;
    Struct2 s2;
    s2.setMember(s);
}
// http://coliru.stacked-crooked.com/a/dd57e8af23f6db4b

疑问1:

打印两个0,因为main中的构造函数和Struct2成员的构造函数。

问题是,我期待三个 0,因为 "setMember" 正在接收 's' 的副本,对吧?那到底发生了什么?

疑问二:

我想把这个:

s2.setMember(std::move(s)); 

因为我不会再使用's',但是setMember 没有指定'&&',可以吗?我也必须这样做吗? :

s = std::move(aux);

还是只有主线就够了?

疑问三:

std::vector<A> vectorA;

int main()
{
    A a;
    // modifies a ...
    vectorA.push_back(std::move(a));
}

是否正确?我在优化任何移动 'a' 吗?它不会再被使用,我想将它保留在向量中

谢谢

because the "setMember" is receiving a copy of 's', right?

嗯,不。它正在接收 const& 并复制赋值运算符。由于您没有重载赋值运算符,因此不会打印任何内容。


s2.setMember(std::move(s));

这不会解决任何问题; std::move 只会将 s 转换为右值,但在函数内部它仍然是 const&.


经验法则:按值传递,向外移动:

void setMember(Struct aux) { s = std::move(aux); }

这样就可以 "automagically" 工作;在接口上复制左值/将右值移动到参数值中,然后将参数值移动到实际的对象成员中。

当然,要充分利用该机器,您需要将右值传递到那里,所以...

Struct s;
Struct2 s2;
s2.setMember(std::move(s));

或者也许...

s2.setMember(Struct());

话虽如此,您的旧代码不会失效。


至于第三个例子,是的,这没问题,虽然我可能要么

  • 将对 a 的更改移动到另一个函数并 push_back(function())
  • 将对 a 的更改移动到 A 的构造函数并使用 emplace_back