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
我有这个示例代码:
#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