C++流作为一个参数的时候载运营商<<
-
25-09-2019 - |
题
我试着写我自己的记录类和使用它作为一个流:
logger L;
L << "whatever" << std::endl;
这是代码我开始:
#include <iostream>
using namespace std;
class logger{
public:
template <typename T>
friend logger& operator <<(logger& log, const T& value);
};
template <typename T>
logger& operator <<(logger& log, T const & value) {
// Here I'd output the values to a file and stdout, etc.
cout << value;
return log;
}
int main(int argc, char *argv[])
{
logger L;
L << "hello" << '\n' ; // This works
L << "bye" << "alo" << endl; // This doesn't work
return 0;
}
但我得到一个错误,当试图以汇编,他说,没有定义对于操作者<< (当使用std::endl):
pruebaLog.cpp:31: error: no match for ‘operator<<’ in ‘operator<< [with T = char [4]](((logger&)((logger*)operator<< [with T = char [4]](((logger&)(& L)), ((const char (&)[4])"bye")))), ((const char (&)[4])"alo")) << std::endl’
所以,我已经试图过载操作员<< 接受这种流,但它的驾驶我的疯狂。我不知道如何做到这一点。我已经供不同的天,例如,定义的标准::endl在ostream头文件,并写了一个功能用这个标题:
logger& operator <<(logger& log, const basic_ostream<char,char_traits<char> >& (*s)(basic_ostream<char,char_traits<char> >&))
但是没有运气。我已经尝试过同样的使用模板,而不是直接使用的字符,并且还试图简单地使用"const ostream和操作系统",并没有什么。
另一件事错误我是这样的,在错误输出,第一个参数对于操作者<< 变化,有时这是一个参照指针,有时候看起来就像一个双人引用...
解决方案
endl
是一个怪兽。它不是一个恒定值。这是所有的东西,一个功能其实,。你需要一个特殊的覆盖处理endl
的应用程序:
logger& operator<< (logger& log, ostream& (*pf) (ostream&))
{
cout << pf;
return log;
}
此接受接受一个ostream
参考并返回ostream
基准的函数的插入。这就是endl
是。
编辑:针对FranticPedantic的有趣的问题:“为什么不能编译演绎这个自动?”。原因是,如果你深入,更深入,endl
实际上本身就是一个的模板的功能。它的定义为:
template <class charT, class traits>
basic_ostream<charT,traits>& endl ( basic_ostream<charT,traits>& os );
也就是说,它可以采取任何形式如ostream
其输入和输出的。所以,问题不在于编译器不能推断出T const &
可能是一个函数指针,但它无法弄清楚的你的意思是通过在的endl
。operator<<
的模板版本介绍在这个问题将接受一个指向任何函数作为第二个参数,但在同一时间,endl
模板表示的无限的成组的潜在功能,所以编译器不能做任何有意义那里。
,它提供其第二个参数的operator<<
的特殊过载相匹配的特定的endl
模板的实例化允许呼叫的决心。
其他提示
endl
是一个IO操纵器,它是通过参考接受流的算符,在其上执行一些操作,并且返回该流,也通过引用。 cout << endl
相当于cout << '\n' << flush
,其中flush
是刷新输出缓冲区的操纵器。
在你的类,你只需要编写这个操作符的重载:
logger& operator<<(logger&(*function)(logger&)) {
return function(*this);
}
其中logger&(*)(logger&)
是接受并通过引用返回logger
的功能的类型。写自己的操纵,只写一个函数相匹配的签名,并且有它的流执行一些操作:
logger& newline(logger& L) {
return L << '\n';
}
我认为,问题是你的流不超载 operator<<
接受一种功能,具有相同的类型 std::endl
如图所示,在这个回答: std::endl是不明型号的时候载运营商<<
在C ++它是一个封装的基础I / O机理探讨的流缓存器即可。流本身仅封装转换为字符串,并且I / O方向。
因此,你应该使用预定义的流类中的一个,而不是让你自己。如果你有你想要你的I / O去(如系统日志)的新目标,你应该建立的是你自己的流缓冲的(来自std::streambuf
派生)。