C ++流作为参数,当重载operator<< [英] C++ stream as a parameter when overloading operator<<

查看:468
本文介绍了C ++流作为参数,当重载operator<<的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想写自己的日志类并将其用作流:

I'm trying to write my own logging class and use it as a stream:

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时):

But I was getting an error when trying to compile, saying that there was no definition for operator<< (when using 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’

所以,我一直在尝试重载operator<接受这种流,但它驱动我疯了。我不知道该怎么做。例如,我在ostream头文件中定义了std :: endl,并用这个头文件写了一个函数:

So, I've been trying to overload operator<< to accept this kind of streams, but it's driving me mad. I don't know how to do it. I've been loking at, for instance, the definition of std::endl at the ostream header file and written a function with this header:

logger& operator <<(logger& log, const basic_ostream<char,char_traits<char> >& (*s)(basic_ostream<char,char_traits<char> >&))

但没有运气。我试过相同的使用模板,而不是直接使用char,也尝试简单地使用const ostream& os,没有什么。

But no luck. I've tried the same using templates instead of directly using char, and also tried simply using "const ostream& os", and nothing.

另一件事,在错误输出中,操作符<<有时它是一个指针,有时看起来像一个双引用...

Another thing that bugs me is that, in the error output, the first argument for operator<< changes, sometimes it's a reference to a pointer, sometimes looks like a double reference...

推荐答案

endl 是一个奇怪的野兽。它不是一个常数值。事实上,它是一个函数。您需要一个特殊的覆盖来处理 endl 的应用程序:

endl is a strange beast. It isn't a constant value. It's actually, of all things, a function. You need a special override to handle the application of endl:

logger& operator<< (logger& log, ostream& (*pf) (ostream&))
{
  cout << pf;
  return log;
}

这接受插入一个函数,该函数需要一个 ostream 引用并返回 ostream 引用。这是 endl

This accepts insertion of a function that takes an ostream reference and returns an ostream reference. That's what endl is.

编辑:为了回应FranticPedantic的有趣的问题为什么编译器不能自动推导出来呢?原因是,如果你还深入, endl 实际上是一个模板函数。它定义为:

In response to FranticPedantic's interesting question of "why can't the compiler deduce this automatically?". The reason is that if you delve yet deeper, endl is actually itself a template function. It's defined as:

template <class charT, class traits>
  basic_ostream<charT,traits>& endl ( basic_ostream<charT,traits>& os );

也就是说,它可以采用任何类型的 ostream 作为其输入和输出。所以问题不是编译器不能推导出 T const& 可能是一个函数指针,但它不能找出 / em> endl 您打算传入。问题中提出的运算符<< 的模板版本一个指向任何函数的指针作为它的第二个参数,但同时 endl 模板代表一个无限的潜在函数集合,因此编译器

That is, it can take any sort of ostream as its input and output. So the problem isn't that the compiler can't deduce that T const & could be a function pointer, but that it can't figure out which endl you meant to pass in. The templated version of operator<< presented in the question would accept a pointer to any function as its second argument, but at the same time, the endl template represents an infinite set of potential functions, so the compiler can't do anything meaningful there.

提供运算符<< 的第二个参数匹配的特殊重载 endl 模板的特定实例化允许呼叫解析。

Providing the special overload of the operator<< whose second argument matches a specific instantiation of the endl template allows the call to resolve.

这篇关于C ++流作为参数,当重载operator&lt;&lt;的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆