【发布时间】:2021-10-18 21:30:28
【问题描述】:
这是通过移动语义将 std::string 参数传递给 Impl 的构造函数的正确方法吗?
#include <string>
#include <memory>
using namespace std;
class Foo
{
struct Impl;
unique_ptr<Impl> impl_;
public:
Foo(string s);
};
struct Foo::Impl
{
string s_;
Impl(string s) : s_(std::move(s)) {}
};
Foo::Foo(string s) : impl_(make_unique<Foo::Impl>(move(s)))
{
}
或者应该将Impl的ctor定义为:
Impl(string&& s) : s_(std::move(s)) {}
【问题讨论】:
-
使用右值引用可能会使代码更快一点,因为它会减少移动。与往常一样,尝试两者并衡量结果。根据字符串的大小,以及如果您使用 SSO 实现,删除一个移动可能会产生很大的不同,或者它可能并不重要。
-
对于右值参考案例,我需要 Impl 的 ctor 中的 std::move() 吗?无论有没有移动调用,它都可以编译。
-
是的,您仍然需要使用
std::move。任何有名字的东西都是左值,包括右值引用,所以如果你想让移动发生,你需要用std::move将它转换回右值。 -
我明白了,所以没有 std::move() s_ 只会被复制构造?
-
是的。没有它,你就有了一个左值,除非你使用
std::move,否则它们永远不会被移动。该语句有几个边缘情况,但它们处理具有自动存储持续时间的本地对象,并且要么被返回,要么被抛出本地范围之外。
标签: c++ c++11 move-semantics