这里不是const修饰符吗?

zou*_*yjs 45 c++ coding-style const rvalue c++11

" Effective C++ "第3项说"尽可能使用const",它给出了一个例子:

const Rational operator*(const Rational& lhs, 
                            const Rational& rhs);
Run Code Online (Sandbox Code Playgroud)

防止客户端犯下这样的暴行:

Rational a, b, c;
...
(a * b) = c;   // invoke operator= on the result of a*b!
Run Code Online (Sandbox Code Playgroud)

但是,函数的非参考返回值是否已经是一个rvalue?那么为什么还要这么做呢?

Tem*_*Rex 51

关键是对于类类型(但不是内置类型),a = b只是一个简写a.operator=(b),其中operator =是一个成员函数.并且可以在由其(a * b)创建的rvalues上调用成员函数Rational::operator*.为了强制执行与内置右值相似的语义(" 插件那样做 "),一些作者(Meyers包括)在C++ 98中推荐使用const-rvalue返回具有此类运算符的类.

然而,在C++ 11中,const-rvalue返回是一个坏主意,因为它将禁止移动语义,因为const rvalues无法绑定T&&.

在他的笔记中对新C++(C++ 11)的概述,Scott Meyers从他的旧书中给出了完全相同的例子,并得出结论,现在认为添加const返回值的设计很差.现在推荐签名

Rational operator*(const Rational& lhs, const Rational& rhs);
Run Code Online (Sandbox Code Playgroud)

更新:正如@ JohannesSchaub-litb在评论中暗示的那样,在C++ 11中你也可以在赋值运算符上使用引用限定符,这样它只接受左值作为左参数(即*this指针,这就是为什么这个特性也被称为"*this的右值参考".你需要g ++> = 4.8.1(刚刚发布)或Clang> = 2.9才能使用它.

  • 禁止该赋值的正确方法是`Rational&operator =(const Rational&other)&;` (17认同)
  • @ Barmaley.exe:因为移动语义需要一个非const对象(你怎么能*移动* - 即修改 - 否则这个对象?). (4认同)
  • @ Barmaley.exe:好吧,我曾经不同意Andy(以及他与你联系的答案).你可以将语言弯曲成各种各样的东西,但弯曲语义是明显的邪恶.移动意味着修改两个对象的可见状态(移动到/移动),`const`意味着你不能修改可见状态,这只是语义上的不兼容.仅仅因为你可以用脚射击自己并不意味着你应该. (3认同)
  • @ Barmaley.exe:当然`mutable`会起作用但是这会破坏const-correctness:你必须使`mutable`几乎成为一个可移动类的每一个成员,然后constness再也没有任何意义了. (2认同)

And*_*ard 7

返回值上的const修饰符不是必需的,可能会阻碍移动语义.防止在C++ 11中赋值给rvalues的首选方法是使用" ref-qualifiers".

struct Rational
{
  Rational & operator=( Rational other ) &; // can only be called on lvalues
};

Rational operator*( Rational const & lhs, Rational const & rhs );

Rational a, b, c;

(a * b) = c; // error
Run Code Online (Sandbox Code Playgroud)


Bat*_*eba 5

也许这会花费我的代表点,但我不同意.不要修改重载运算符的预期返回类型,因为它会使您的类的用户烦恼.即使用

Rational operator*(const Rational& lhs, const Rational& rhs);
Run Code Online (Sandbox Code Playgroud)

(当然,const荷兰国际集团的参数是很好的做法,并具有一定的基准参数,甚至更好,因为它意味着编译器不会采取深层副本.但在这种情况下,没有一个恒定的参考返回值,虽然,你会得到一个悬挂参考是灾难性的.但请注意,有时候,参考比通过值慢.我认为doubles和ints在许多平台上都属于那个类别.)