我正在实现一个使用流操作符的日志类。基本思想是自定义类型可以实现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
。有什么想法吗?
此外:有没有办法直接为operator<<
提供log_stream&
重载,而不是std::ostream
(如果有人希望记录两个不同的重载 - 与{{1一起使用) - 例如序列化到磁盘 - 与log_stream
一起使用)?
编辑#1
如果添加了'具有r值的'fstream
,则第一个问题就解决了。
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, ...>
的基类,它应该可以在这里获得对这个基类的引用,不应该吗?
编辑#2
嗯,它当然应该调用成员log_stream
,这使它成功。
operator<<
所以问题已经解决了C ++ 11 - 但它仍然不适用于C ++ 03( argh )。
我想到的一个解决方案是以最短的形式template <typename Type> inline log_stream &operator<<(log_stream &&stream, Type&& type)
{
stream << std::forward<Type>(type);
return stream;
}
提供'l值到l值转换运算符'。
operator()
不漂亮,但有些东西。还有更好(更漂亮)的想法吗?
答案 0 :(得分:2)
您的日志流是临时,而插入运算符需要非const引用。你无法将前者转换为后者。
您必须引入log_stream
类型的实际命名变量,并将其用作<<
的左操作数。