c++ - 使用 const 对象 move 语义

标签 c++ c++11 move-semantics

我有这样的代码:

class Pair{
public:
    Pair(Pair && other){};

    Pair(Pair & other){};
};

class IROList{
public:
    virtual const Pair get(const char *key) const = 0;

    inline const Pair operator[](const char *key) const{
        return this->get(key);
        // error: binding ‘const Pair’ to reference of type ‘Pair&&’ discards qualifiers
    }
};

编译时产生

error: binding ‘const Pair’ to reference of type ‘Pair&&’ discards qualifiers

如果我将 move 构造函数更改为 const,错误就会消失。

    Pair(const Pair && other){};

但是,如果 move 构造函数采用const,我就无法真正 move 数据。我应该复制它。

除了删除返回方法的 const 之外,是否有任何解决方法,例如

    virtual Pair get(const char *key) const = 0;
    inline Pair operator[](const char *key) const;

最佳答案

问题是你没有很好地实现你的拷贝构造函数。

代替:

Pair(const Pair & other){};

你写的

Pair(Pair & other){};

这会导致构造函数只接受左值变量,而不接受临时变量,因为只有 const 引用可以绑定(bind)到临时变量和右值引用。

这会强制编译器从 get 返回 Pair 作为右值引用( move 语义),因为它返回一个临时值并且它不知道如何复制它,只知道如何 move 它。同样,临时对象只能被 const 引用或 r-value-reference 捕获。

r-value-references 不是 const - 这是它们的全部存在!被捕获,他们的内容将被另一个对象窃取。

为了证明我的观点,这里是 GCC 编译器输出你的代码(无常量):
http://coliru.stacked-crooked.com/a/c390189089434f30 - 不编译

和常量:
http://coliru.stacked-crooked.com/a/0db0fc767e6f10f2 - 没有编译器错误。

除此之外,我建议您查看 std::map 实现或类似的类。对于 operator [] 应该是什么样子、它返回什么以及为什么返回,开发人员之间有一些共识。 良好的软件设计远比 move 语义等非常具体的功能重要。

关于c++ - 使用 const 对象 move 语义,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31481620/

相关文章:

c++ - 如何在 ubuntu 20.04 中预编译 <bits/stdc++.h> 头文件?

c++ - 在 C++ 中将数字转换为字符串的最佳方法?

c++ - 依赖于模板参数的成员变量和构造函数

c++ - 如何强制 std::sort 使用 move 构造函数和 move 赋值?

c++ - 如何确保 std::tuple 在以下代码中使用 c++11 move 语义

C++ move 复制构造函数和 move 赋值运算符

c++ - 了解 Levenberg Marquardt 枚举返回。

c++ - 我如何(或者我可以安全地,或者我可以) move 一个 const 对象?

c# - C++ 将二维数组构造成 C#

c++ - 不一致的警告 "conversion from ' const unsigned char' to 'const float' requires a narrowing conversion”