操作员<< for enum class just doesn't work

问题描述 投票:0回答:1

我有以下代码:

logging.hxx

#include <iostream>
#include <string>
#include <sstream>

#include "singleton.hxx"
#include "utils.hxx"

class FGaugeLogger: public Singleton<FGaugeLogger> {
    public:
        enum class LogLevel: int {
            DEBUG = 0,
            INFO = 1,
            WARNING = 2,
            ERROR = 3,
            FATAL = 4,
        };
        
        FGaugeLogger() {};
        
        template<typename T>
        void log(LogLevel level, const T& msg) {
            if (level >= _level) {
                if (level >= LogLevel::WARNING) {
                    std::cerr << "[" << level << "] " << msg << std::endl;
                } else {
                    std::cout << "[" << level << "] " << msg << std::endl;
                }
            }
        }
    
    private:
        LogLevel _level {LogLevel::DEBUG};
};

std::ostream& operator<<(std::ostream& s, const FGaugeLogger::LogLevel level);

#define LOG(level, expr) \
    std::stringstream ss; \
    ss << expr; \
    std::string str = ss.str(); \
    FGaugeLogger::instance()->log(FGaugeLogger::LogLevel::level, ss.str());

logging.cxx

#include "logging.hxx"

std::ostream& operator<<(std::ostream& s, FGaugeLogger::LogLevel level) {
    s << "level";
    return s;
}

main.cxx

#include "logging.hxx"

int main(int argc, char* argv[]) {
    LOG("info message");
    return 0;
}

编译时会给出以下消息,然后是 100 个都不匹配的重载:

In file included from /media/frederic/WD-5TB/.fg/Programme/fgauge/src/main.cxx:1:
/media/frederic/WD-5TB/.fg/Programme/fgauge/src/logging.hxx: In member function ‘void FGaugeLogger::log(FGaugeLogger::LogLevel, const T&)’:
/media/frederic/WD-5TB/.fg/Programme/fgauge/src/logging.hxx:27:58: error: no match for ‘operator<<’ (operand types are ‘std::basic_ostream<char>’ and ‘FGaugeLogger::LogLevel’)
   27 |                                         std::cerr << "[" << level << "] " << msg << std::endl;
      |                                         ~~~~~~~~~~~~~~~~ ^~ ~~~~~
      |                                                   |         |
      |                                                   |         FGaugeLogger::LogLevel
      |                                                   std::basic_ostream<char>

你知道这里可能出什么问题吗? AFAICS 我的代码与类似问题的答案中的第三个示例相同。

c++ enums operator-overloading operators enum-class
1个回答
0
投票

问题是 C++ 文件是从上到下解析的,而且顺序通常很重要。在你写的地方:

std::cerr << "[" << level << "] " << msg << std::endl;

operator<<
FGaugeLogger::LogLevel
尚未定义。

一个简单的修复方法是将其声明为类内的

friend

class FGaugeLogger: public Singleton<FGaugeLogger> {
  public:
    enum class LogLevel: int {
        DEBUG = 0,
        INFO = 1,
        WARNING = 2,
        ERROR = 3,
        FATAL = 4,
    };
    // note: parameter names are optional, and it's probably better to omit them
    friend std::ostream& operator<<(std::ostream&, FGaugeLogger::LogLevel);
    // ...
};
© www.soinside.com 2019 - 2024. All rights reserved.