2

我正在实现一个使用流运算符的日志记录类。基本思想是自定义类型可以实现一个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_streamis-a ostringstreamis-a basic_ostringstreamis-a basic_ostream。有任何想法吗?

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

编辑#1

如果添加“r 值能力” operator<<,第一个问题就解决了。

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

但是,它现在/仍然在类型转换为基类(无论是它ostringstream还是ostream)时中断。

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

好吧,它当然应该调用 member 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";

不漂亮,但有点。有更好(更漂亮)的想法吗?

4

1 回答 1

2

您的日志流是临时的,而插入运算符需要非常量引用。您不能将前者转换为后者。

您必须引入一个实际的命名变量类型log_stream并将其用作<<.

于 2013-04-21T13:37:26.517 回答