编写自定义 ostream 运算符的现代模式
Modern pattern to write custom ostream operator
通常,在 C++ 中,我们过去常常这样定义自定义 ostream operator<<
:
class A {
int impl_;
friend std::ostream& operator<<(std::ostream& os, A const& self){
return os << "A:" << self.impl_;
}
};
但是现在,post C++11,有右值引用,事实上,内置类型可以流式传输到右值std::ostream
引用。
现在允许:
int i = 5;
std::ofstream("file") << i;
(我不知道这是否是定义特殊重载的原因。)
这是否意味着为了保持一致性,应该为自定义 类 定义两个运算符?像这样,
class A {
int impl_;
friend std::ostream& operator<<(std::ostream& os, A const& self) {
return os << "A:" << self.impl_;
}
friend std::ostream&& operator<<(std::ostream&& os, A const& self) {
os << "A:" << self.impl_;
return std::move(os);
}
};
或更精简,
class A {
int impl_;
friend std::ostream& operator<<(std::ostream& os, A const& self) {
return os << "A:" << self.impl_;
}
friend std::ostream&& operator<<(std::ostream&& os, A const& self) {
return std::move(os << self); // calls the other overload
}
};
如今在 C++11 中重载 operator<<
的推荐方法是什么?
除了概念上的讨论,从技术角度来看:
经过一些实验,我意识到我不需要为 r-value ostream 重载,库已经为我完成了。
只需要 l-value 版本并且库有一些 r-value 版本被转发到实现的重载,这大概适用于 operator << 通过 ADL 的任何 std 命名空间参数什么的。
因此,在 C++11 中,这是允许的 std::ofstream{"file"} << a
,即使没有 r-value 重载(对于流)是自定义定义的。
这似乎使 operator<<
在 STL 中很特别。
欢迎指正。
通常,在 C++ 中,我们过去常常这样定义自定义 ostream operator<<
:
class A {
int impl_;
friend std::ostream& operator<<(std::ostream& os, A const& self){
return os << "A:" << self.impl_;
}
};
但是现在,post C++11,有右值引用,事实上,内置类型可以流式传输到右值std::ostream
引用。
现在允许:
int i = 5;
std::ofstream("file") << i;
(我不知道这是否是定义特殊重载的原因。)
这是否意味着为了保持一致性,应该为自定义 类 定义两个运算符?像这样,
class A {
int impl_;
friend std::ostream& operator<<(std::ostream& os, A const& self) {
return os << "A:" << self.impl_;
}
friend std::ostream&& operator<<(std::ostream&& os, A const& self) {
os << "A:" << self.impl_;
return std::move(os);
}
};
或更精简,
class A {
int impl_;
friend std::ostream& operator<<(std::ostream& os, A const& self) {
return os << "A:" << self.impl_;
}
friend std::ostream&& operator<<(std::ostream&& os, A const& self) {
return std::move(os << self); // calls the other overload
}
};
如今在 C++11 中重载 operator<<
的推荐方法是什么?
除了概念上的讨论,从技术角度来看:
经过一些实验,我意识到我不需要为 r-value ostream 重载,库已经为我完成了。
只需要 l-value 版本并且库有一些 r-value 版本被转发到实现的重载,这大概适用于 operator << 通过 ADL 的任何 std 命名空间参数什么的。
因此,在 C++11 中,这是允许的 std::ofstream{"file"} << a
,即使没有 r-value 重载(对于流)是自定义定义的。
这似乎使 operator<<
在 STL 中很特别。
欢迎指正。