c++ - 为人工运算符重载返回引用是否有效?
问题描述
众所周知,我们通常在重载算术运算符时将副本返回给新类。例如,<<
运算符通常定义如下:
T1 operator<<(const T1& a, const T2& b) {
// apply b
return a;
}
但我想知道在这种情况下返回引用是否通常有效。例如,以下代码是否可能会产生任何无效情况?
T1& operator<<(T1& a, const T2& b) {
// apply b
return a;
}
为什么我需要这个?假设我有这样的代码:
class B {
public:
B() {}
~B() { std::cout << ss_.str() << "\n"; }
template<typename T>
B& operator<<(T val) {
ss_ << val;
return *this;
}
private:
std::stringstream ss_;
};
int main() {
B{} << "str" << "abc" << 1;
B{} << "str2" << "abc2" << 2;
}
在这段代码中,类型的构造函数和析构函数T1
将只被调用一次,这将非常适合这里。但是,如果我为运算符按值返回,<<
则将为每个临时右值调用构造函数和析构函数,这对我的用例来说不是很好。
通过引用返回是否有可能为重载这些运算符创建无效代码?
解决方案
是的,它不仅有效,而且是<<
流输出重载时的常见习语。例如:
std::ostream& operator<<(std::ostream& os, const MyData& data) {
os << data.a << ',' << data.b << ',' << data.c;
return os;
}
推荐阅读
- omnet++ - OMNET++:如何在 INET 4.0 的离散 NxN 空间中移动节点?
- php - 在 codeigniter 中逃避了足够的 sql 注入保护
- r - 生成矩阵,其中每个新列是前一列的倍数
- c++ - 一对 C++ 交换方法的优点是什么?
- javascript - 动态增加字体大小
- string - 如何在 F# 中使用 String.iter
- javascript - 使用 Image URI 将照片上传到 Firebase 存储
- javascript - 数据触发器与 fancybox 冲突
- php - 提供的参数之一不可接受使用 Microsoft Graph API 创建文件夹
- php - PHP在csv的每个值的两端添加引号