c++ - 如果对象是右值,确保成员变量被移动

标签 c++ c++11 c++14 rvalue

请考虑以下代码:

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/

相关文章:

c++ - 测试模板参数的签名

c++ - 为什么默认情况下全局命名空间中没有 C++14 标准定义的文字?

C++ RapidXml - 使用 first_node() 遍历以修改 XML 文件中节点的值

c++ - Lambda 通过引用捕获并在槽中使用

c++ - 如何在 Windows XP 上正确安装 ffmpeg?

c++ - 如何将 D3DVERTEXELEMENT9 声明移动到 header

c++ - 在碰撞检测 c++ opengl 中反弹后降低球的速度

c++ - 将函数绑定(bind)到类型的更好语法?

c++ - 函数参数的嵌套模板参数和 cv- 和 ref- 限定符

c++ - `static constexpr` 在常量表达式中调用的函数是...错误?