You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在自定义Logger类的operator<<中支持std::hex格式化?

问题

我已经在自定义Logger类中实现了operator<<重载,代码如下:

#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>" }
    };
};

现在我希望该Logger能支持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&)

请问如何解决此问题,使Logger支持std::hex格式化?

解决方案

  • 处理操纵符函数的重载
    编译错误的核心原因是std::hex、std::dec这类属于ios操纵符函数,它们的类型是std::ios_base&(*)(std::ios_base&),而你的Logger类没有提供对应的operator<<重载来处理这类函数。

    添加以下友元重载即可让Logger传递这些操纵符到底层的输出流:

    #include <iostream> // 必须包含此头文件以引用std::ios_base
    
    friend Logger& operator<<(Logger& logger, std::ios_base& (*manip)(std::ios_base&)) {
        if (logger.currentSeverity >= logger.loggerSeverity) {
            manip(logger.outputStream);
        }
        return logger;
    }
    

    这个重载会把操纵符直接应用到Logger内部的outputStream上,后续的数值输出就会遵循指定的格式(比如十六进制)。

  • 添加数值类型的输出重载
    你当前的Logger只实现了const char*类型的输出,而record->metaData.crc和crc32是整数类型,所以还需要补充对应的数值类型重载,比如:

    #include <sstream> // 要包含这个头文件来使用std::ostringstream
    
    // 处理无符号整数
    friend Logger& operator<<(Logger& logger, unsigned int value) {
        if (logger.currentSeverity >= logger.loggerSeverity) {
            // 如果需要在logLines中保存格式化后的内容,先转成字符串再存入
            std::ostringstream oss;
            oss << logger.outputStream.flags() << value;
            logger.logLines.push_back(oss.str());
            // 输出到底层流
            logger.outputStream << value;
        }
        return logger;
    }
    
    // 处理有符号整数
    friend Logger& operator<<(Logger& logger, int value) {
        if (logger.currentSeverity >= logger.loggerSeverity) {
            std::ostringstream oss;
            oss << logger.outputStream.flags() << value;
            logger.logLines.push_back(oss.str());
            logger.outputStream << value;
        }
        return logger;
    }
    

    如果需要支持long、long long等其他数值类型,按照同样的模式添加重载即可。

  • 额外注意点

    • 必须包含<iostream>和<sstream>头文件,否则会出现类型未定义的错误。
    • 如果不需要在logLines中记录格式化后的数值内容,可以省略std::ostringstream相关的逻辑,直接输出到底层流即可。

内容的提问来源于stack exchange,提问作者binaryBigInt

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.25 06:55:56