给出代码:
#include <iostream>
class MyStream {
public:
template <typename T>
MyStream& operator<<(T&& t) {
std::cout << t << std::endl;
return *this;
}
};
struct Test {
int x;
float y;
};
template <typename Stream>
Stream& operator<<(Stream& s, const Test& t) {
return s << t.x << ", " << t.y;
}
int main() {
const Test t = {1, 2.0};
MyStream ms;
ms << t;
Test t2 = {3, 4.0};
ms << t2;
}
它会产生编译错误:
source>:26:8: error: use of overloaded operator '<<' is ambiguous (with operand types 'MyStream' and 'const Test')
ms << t;
~~ ^ ~
<source>:7:15: note: candidate function [with T = const Test &]
MyStream& operator<<(T&& t) {
^
<source>:19:9: note: candidate function [with Stream = MyStream]
Stream& operator<<(Stream& s, const Test& t) {
^
1 error generated.
代码链接:https://godbolt.org/z/Gf51fjTMx
问题:
如果我不更改调用站点代码(
main
函数),如何使两个函数重载中的任何一个更加专门化?
template <class C, class T>
std::basic_ostream<C, T>&
operator<<(std::basic_ostream<C,T>& s, const Test& t) {
return s << t.x << ", " << t.y;
}
更好的是,根本不要编写像
MyStream
这样的类,它们往往很脆弱。如果您需要专门的流,请从 std::basic_{i,o}stream
派生自己的流和/或编写自己的 streambuf
实现。
更好的是,放弃 ostream 格式,转而使用
std::format
。