如何重载不带或返回ostream的operator <<
-
08-07-2019 - |
题
原始问题
我正在编写一个日志记录类,目标是能够做到这一点: 通用标签
当前,我的Logger标头看起来像这样: 通用标签
有关此类的一些说明:
- 跨平台兼容性不是问题。
- 在Logger.cpp中,有一个单例类,负责创建“真实的” ostream。
- Logger构造函数和解构函数对单例执行必要的锁定。
我有三个问题:
- 如何使运算符<<成为朋友或成员,以便可以将out_stream设置为私有?
- 如何使操作员<<功能适用于机械手?
- 如何添加特殊化,以便如果T为WCHAR *或std :: wstring,它将在将其传递给out_stream之前将其转换为char *或std :: string? (我可以进行转换。对于我来说,丢失高Unicode字符不是问题。)
从答案中学到的东西:
- 在朋友之前而不是之后放置模板。
- std :: ios :: hex不是操纵器。 std :: hex是一个操纵器。
最终结果 通用标签
解决方案
您可以使用好友定义,该定义将在类的周围名称空间中定义运算符,并使它仅对运算符重载解析可见(不能使用:: operator << ...语法手动调用): 通用标签
另一种方法是,保持代码不变,并只使运算符<<成为朋友,您可以将以下行添加到类定义中: 通用标签
对于操纵器问题,我只想给我我之前写的代码: 通用标签
};
请注意,它是std :: hex,但不是std :: ios :: hex 。后者用作流的setf
函数的操纵器标志。请注意,对于您的示例,不需要对操纵器进行特殊处理。只需对std :: endl进行上述特殊处理,因为使用std :: endl时,我确实会流时间。
其他提示
使用模板是正确的方法,但是只需确保模板位于 header 文件(logger.h
或您所称的名称)中,则不。这将自动适用于任何已用operator <<
定义了std::ostream
的类型。它还将自动与流操纵器对象一起使用-这些对象实际上只是带有std::ostream
参数的函数,而operator <<
只是调用ostream
上的函数。
您可以使operator <<
成为朋友函数,如下所示:
通用标签
专业化很容易-只需使用模板专业化(同样,在头文件中): 通用标签
无需声明友谊: 通用标签
为什么不使用printf方式并使用多参数方法(带有三个点...)。这仍然为您提供了强大的格式化能力,并且不会像使用<<时那样使您感到混乱。
例如: 通用标签
等待两秒钟,请帮忙为您准备一个代码示例。
编辑: 通用标签
如果您想将此类用作一个类而不是一个独立的函数,则可以使记录器运算符()重载,并且它的工作原理相同