用const对象移动语义

Nic*_*ick 0 c++ move-semantics c++11

我有这样的代码:

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
    }
};
Run Code Online (Sandbox Code Playgroud)

在编译时,它产生

error: binding ‘const Pair’ to reference of type ‘Pair&&’ discards qualifiers
Run Code Online (Sandbox Code Playgroud)

如果我将移动构造函数更改为const,则错误消失.

    Pair(const Pair && other){};
Run Code Online (Sandbox Code Playgroud)

但是,如果移动构造函数采用const,我无法真正移动数据.我应该复制它.

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

    virtual Pair get(const char *key) const = 0;
    inline Pair operator[](const char *key) const;
Run Code Online (Sandbox Code Playgroud)

Dav*_*aim 6

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

代替 :

Pair(const Pair & other){};
Run Code Online (Sandbox Code Playgroud)

你写了

Pair(Pair & other){};
Run Code Online (Sandbox Code Playgroud)

这会导致构造函数只接受l值变量,而不接受临时变量,因为只有const引用可以绑定到temporaries和r值引用.

这迫使编译器从get返回Pair作为r值引用(移动语义),因为它返回一个临时的,它不知道如何复制它,只知道如何移动它.再次,临时只能通过const引用或r值引用来捕获.

r值引用不是常量 - 这是它们的全部存在!被抓住,他们的内容将被另一个对象窃取.

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

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

除此之外,我建议你看看std::map实现或类似的类.开发人员之间对于operator []应该如何看待以及它返回的内容和原因有一些协议.良好的软件设计比移动sematincs等非常具体的功能更为重要.