我在我的
operator<<
类中编写了自己的Logger
实现:
#pragma once
#include <map>
#include <vector>
#include <string>
class Logger
{
public:
enum Severity
{
INFORMATION = 0,
WARNING = 1,
ERROR = 2
};
Logger( std::ostream &os, Logger::Severity severity )
: outputStream( os ), loggerSeverity( severity ) {}
const std::vector<std::string>& getLogLines() const { return logLines; }
friend Logger& operator<<( Logger &logger, Logger::Severity severity ) {
logger.currentSeverity = severity;
logger.outputStream << logger.severityMap.find( severity )->second << ": ";
return logger;
}
friend Logger& operator<<( Logger &logger, const char *logLine ) {
if( logger.currentSeverity >= logger.loggerSeverity )
{
logger.logLines.push_back( logLine );
logger.outputStream << logLine;
}
return logger;
}
private:
std::ostream &outputStream;
Logger::Severity loggerSeverity;
std::vector<std::string> logLines;
Logger::Severity currentSeverity;
const std::map<Logger::Severity, std::string> severityMap =
{
{ Logger::Severity::INFORMATION, "<INF>" },
{ Logger::Severity::WARNING, "<WARN>" },
{ Logger::Severity::ERROR, "<ERR>" }
};
};
现在我想知道如何支持
std::hex
格式?我希望能够像这样调用我的记录器:
logger << Logger::Severity::ERROR << "CRC mismatch ( expected 0x" << std::hex << record->metaData.crc << " but got 0x" << std::hex << crc32 << std::dec << " )" << "\n";
但我得到:
error: no match for ‘operator<<’ (operand types are ‘Logger’ and ‘std::ios_base&(std::ios_base&)’)
79 | logger << Logger::Severity::ERROR << "CRC mismatch ( expected 0x" << std::hex << record->metaData.crc << " but got 0x" << std::hex << crc32 << std::dec << " )" << "\n";
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ^~ ~~~~~~~~
| | |
| Logger std::ios_base&(std::ios_base&)
std::ostream
是如何做到的?
std::hex 是一个带有签名的函数“操纵器”
std::ios_base& hex( std::ios_base& str );
另请参阅 https://en.cppreference.com/w/cpp/io/manip/hex
并且 ostream 对于“输出”函数有一个重载,如下所示:
basic_ostream& operator<<( std::ios_base& (*func)(std::ios_base&) );
另请参阅 https://en.cppreference.com/w/cpp/io/basic_ostream/operator_ltlt
下的 (18)您可以为此类型定义自己的运算符
<<
,将其传递到底层流。
如果你想自己处理它,你需要一些
std::ios_base
类型的东西,你可以给操纵器作为参数,它会做相当于 .setf(std::ios_base::hex, std::ios_base::basefield)
的事情。
或者你必须发明自己的操纵器而不是使用标准操纵器。