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)
问题是你没有很好地实现你的拷贝构造函数.
代替 :
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等非常具体的功能更为重要.