c++ - 使用右值引用作为其左侧操作数来重载加法运算符是否被认为是一种好的做法?

标签 c++ c++11 operator-overloading rvalue-reference

假设 str 是一个用于存储字符串值的类,它将重载加法运算符以支持字符串连接。像这样:

str operator+(const str &a,const str &b);

但问题是如果我们有这样的东西:

str s=str("Hel") + str("lo ") + str("Wor") + str("ld!");

然后它会创建 3 个临时对象(因为我们在每次添加时都会得到一个新对象),这在这个上下文中并不是真正需要的。 此问题的一个简单解决方案可能是重载一个新的加法运算符,该运算符接受右值引用作为其左操作数,并在将其与右操作数连接后将此操作数也作为右值引用返回。像这样:

str &&operator+(str &&a,const str &b){
   a+=b;
   return std::move(a);
}

通过重载此运算符,上述语句将仅创建一个临时对象,并且后续添加将仅连接到该临时对象。

我的问题是,这种方法是解决这个问题的正确方法吗?

最佳答案

通常可以有效地移动字符串。

因此,您的 operator+ 应该返回 str 而不是 str&&。这意味着

str const& bob = str1 + str2;

不会坏得很厉害,或者更合理地说:

for(char c : str1 + str2)

不会坏得很厉害。

其次,只需按值获取 str。如果它是右值,它将被移入(便宜)。如果它是一个左值,它将被复制(然后扩展,然后返回)。也很便宜。

str operator+( str lhs, str const& rhs )

最后,您可以使 rhs 成为任何可转换为 str(或 valid-to-add-to-str)的模板类型,以便可能删除无用的转换。

特别是

str a = str("Hello") + " world";

应该构造"Hello",然后附加"world"而不构造另一个str对象,然后将该结果移入a

您可以编写一个 + 来对称地处理左右两侧的右值,但这是可行的,具有讽刺意味的是,链式 + 将右值放在左边,因为链式 + 如何绑定(bind)其参数。

最后,您可以一直使用表达式模板,在分配结果之前(几乎)什么都不做。这有危险,对于像玩具绳类这样简单的东西来说是不值得的。如果您正在编写一个严肃的字符链类,那么在您完成大量其他改进之后可能是值得的。

关于c++ - 使用右值引用作为其左侧操作数来重载加法运算符是否被认为是一种好的做法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32317863/

相关文章:

c++ - 如何避免对 GUI 背后的数据使用全局变量?

c++ - 为什么要向这个宏传递三个参数?

c++ - 将未使用的值初始化为 0 c++ 数组

c++ - 错误实现的强类型枚举的语法?

c++ - 将右值作为右值转发是用例吗?

operator-overloading - 在 Fortran 重载赋值中检查自赋值

c++ - Bool 运算符重载不起作用

operator-overloading - Smalltalk 中的运算符可以重载吗?

c++ - C/C++ 解析器/词法分析器如何区分指针的 '*' 和乘法的 '*'?

c++ - Gtkmm:如何暂停应用程序的执行并等待用户输入?