将右值引用作为左操作数重载加法操作符被认为是一种良好的做法
Is overloading the addition operator with an rvalue reference as its left hand operand considered as a good practice?
假设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
(或有效地添加到str
)的模板类型,以删除可能无用的转换。
str a = str("Hello") + " world";
应该构造"Hello"
,然后追加" world"
,而不构造另一个str
对象,然后将结果移动到a
。
你可以写一个+
来对称地处理左值和右值,但这是工作,讽刺的是,链式+
把右值放在左边,因为链式+
绑定它的参数的方式。
最后,您可以一直使用表达式模板,在赋值结果之前(几乎)什么都不做。这是有危险的,对于像玩具字符串类这样简单的东西来说是不值得的。如果您正在编写一个严肃的字符链类,那么在您完成了一系列其他改进之后,它可能是值得的。
相关文章:
- 有一个打印语句的函数是一种糟糕的编程实践吗
- 在调用接收数组的方法时,模板化数组大小是不是一种糟糕的做法
- 将错误返回给调用方而不是立即在 C++ 中抛出错误是否是一种好的做法
- 在C++中使用变量而不是"#define"来指定数组大小是不是一种糟糕的做法?(C错误:在文件范围内
- 将相同共享指针的副本存储在不同的向量中是否是一种好的做法?
- 使用类在C++中存储和列出变量/方法是否是一种好的做法
- 如果 C 函数仍然可以间接执行(通过回调函数),那么将它声明为静态函数是否是一种不好的做法?
- 使用移位的无符号数字作为数组的索引号是一种很好的做法
- 从 std::string 到 std::array<char,size> 的 memcopy 额外数据是否是一种未定义的行为?
- 在硬件SIMD矢量指针和相应类型之间进行"interpret_cast"是一种未定义的行为吗
- 使用字节向量作为其他类型的原始存储是一种好的做法吗
- 使用boost void分配器是一种糟糕的做法吗
- 在类方法中使用 "this" 指针是否是一种好的做法?
- 抽象类/接口中的空方法是否被认为是一种好的做法?
- 在C++中定义虚拟get和set函数是否被认为是一种好的做法
- 将main()放在C++源代码的顶部是否被认为是一种糟糕的约定
- c++是一种基于组件的体系结构,通过继承实现,被认为是良好的实践
- 将右值引用作为左操作数重载加法操作符被认为是一种良好的做法
- 改变一种方法的保护级别是否被认为是一种良好的做法
- 当我编译我的c++代码时,avast认为这是一种病毒