我有很多operator<<()
函数,它们都是从做类似的事情开始的,所以我想对其进行抽象。这是我试图做的一个最小的可复制案例(去掉了所有的复杂性(。请注意,它不会编译。如果它真的编译了,我希望程序自己在一行上打印数字3。
/*
clang++ -std=c++14 -Wall -Wextra foo.cc -o foo
*/
#include <ostream>
#include <iostream>
using std::cout;
using std::endl;
using std::ostream;
ostream& BaseFunction(ostream& os, const int x) {
return os << x;
}
int main(int argc, char *argv[]) {
cout << BaseFunction(cout, 3) << endl;
}
错误开始如下:
foo.cc:17:8: error: invalid operands to binary expression ('ostream' (aka 'basic_ostream<char>') and
'ostream')
cout << BaseFunction(cout, 3) << endl;
~~~~ ^ ~~~~~~~~~~~~~~~~~~~~~
然后提供了大量的";没有已知的从ostream到T〃的转换;建议。
有人看到我做错了什么吗?
Basefunction(cout, 3)
返回cout
。
因此,最后一行相当于
cout << 3;
cout << cout << endl;
由于cout << cout
毫无意义,因此会出现错误。
您使用了一种非常奇怪和独特的(即糟糕的(模式,使用它的方法是:
BaseFunction(cout, 3) << endl;
请注意,您将输入流作为参数传递给函数,并且由于您将流作为输出返回,并且没有operator<<
的重载同时在左侧和右侧获取流,因此使用C++流的常规方式在这里不起作用。
通常的方法是添加一个operator<<
重载,该重载接受左侧流和右侧自定义对象,并根据需要执行任何操作来显示对象。在您的情况下,将函数替换为不将流作为参数的函数,并返回一个自定义对象,然后您可以使用该对象来重载流运算符。
您所做的基本上是定义一个自定义流操纵器。这可以更像这样实现:
/* clang++ -std=c++14 -Wall -Wextra foo.cc -o foo */
#include <iostream>
using std::cout;
using std::endl;
using std::ostream;
struct myValue {
int value;
};
myValue BaseFunction(const int x) {
return myValue{x};
}
ostream& operator<<(ostream &os, const myValue &v) {
return os << v.value;
}
int main(int argc, char *argv[]) {
cout << BaseFunction(3) << endl;
}
实时演示
你可以试试这个:
BaseFunction(cout, 3);
cout << endl;
我认为ostream不能输出ostream。