请考虑以下代码:
class A
{
public:
A(/* params */) {
// Fill m_data depending on params
}
std::vector<double> get_data() const noexcept {
return m_data;
}
private:
std::vector<double> m_data;
};
std::vector<double> get_data() {
return A{/* suitable params */}.get_data();
}
我想要的是,m_data
被移动 给函数 get_data()
的调用者,即不应该制作拷贝。
我如何确定是这种情况?显然,A{/* suitable params */>
是一个右值。因此,它的成员变量 m_data
在此上下文中是一个右值。那么,再添加一个成员函数就够了吗
std::vector<double> get_data() && noexcept {
return std::move(m_data);
}
最佳答案
使用足够新的编译器(阅读:不是 MSVC 2013),您可以重载右值与左值。
class A {
// ...
std::vector<double> get_data() && noexcept {
return std::move(m_data);
}
std::vector<double> get_data() const & { // not noexcept, could throw
return m_data;
}
// ...
};
或者,左值版本可以返回对 vector 的 const 引用并且是 noexcept,但这意味着您暴露了您在某处有一个物理变量的事实,这会阻止您在未来的重构中更改它。
请注意,您不能拥有一个没有引用限定符的函数和另一个具有引用限定符的函数,它们在其他方面具有相同的名称和参数。这是模棱两可的,编译器应该提示。
关于c++ - 如果对象是右值,确保成员变量被移动,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32141266/