运算符<< std::stringstream 派生类的重载(只是)



我正在实现一个使用流操作符的日志类。基本思想是,自定义类型可以实现一个operator<<,为日志记录提供可读的表示形式。日志类将"收集"各种消息,并在销毁时将它们作为单个日志条目转发(到syslog或其他)。

class log_stream : public std::ostringstream
{
    inline ~log_stream()
    {
        forward_to_log(str().c_str());
    }
};
class custom_type
{
};
std::ostream &operator<<(std::ostream &stream, const custom_type &)
{
    stream << "<custom_type data>";
    return stream;
}
log_stream() << "error in custom type: " << custom_type_variable;

除了语句不是从std::ostream的重载开始而是直接使用自定义类型之外,这实际上工作得很好:

log_stream() << custom_type_variable; // no known conversion from 'log_stream'
                                      // to 'basic_ostream<char, ...>&
                                      // for 1st argument

现在我想知道为什么,因为log_stream是- ostringstream是- basic_ostringstream是- basic_ostream。什么好主意吗?

另外:有没有办法直接为log_stream&而不是std::ostream提供operator<<过载(如果有人想要两个不同的日志过载-与log_stream一起使用-例如序列化到磁盘-与fstream一起使用)?

编辑# 1

如果添加一个'r-value capable'的operator<<,第一个问题就解决了。

template <typename Type> inline log_stream &operator<<(log_stream &&stream, Type&& type)
{
    return operator<<(stream, std::forward<Type>(type));
}

然而,它现在/仍然在类型转换到基类(ostringstreamostream)。

log_stream() << custom_type(); // OK
log_stream() << custom_type() << "text"; // OK
log_stream() << "next"; // non-const lvalue reference to type 'log_stream' cannot bind
                        // to a value of unrelated type 'basic_ostream<char, ...>'

为什么basic_ostream<char, ...>类型无关?它一个log_stream的基类,它应该可以在这里得到对这个基类的引用,不是吗?

编辑# 2

当然,它应该调用成员operator<<,这样它就可以工作了。

template <typename Type> inline log_stream &operator<<(log_stream &&stream, Type&& type)
{
    stream << std::forward<Type>(type);
    return stream;
}

所以这个问题在c++ 11中已经解决了,但是在c++ 03 (argh)中仍然不起作用。

我想到的一个解决方案是提供一个'r值到l值转换运算符',以其最短的形式operator()

class log_stream
{
    inline log_stream &()() 
    {
        return *this;
    }
}
log_stream()() << custom_type() << "text";

不漂亮,但也不错。有更好(更漂亮)的主意吗?

您的日志流是一个临时,而插入操作符需要一个非const引用。不能将前者转换为后者。

必须引入log_stream类型的实际命名变量,并将其用作<<的左操作数。

最新更新