0

我在一个“大”跨平台项目中使用easyloggingpp 。足够大,以至于我无法创建一个简单的运行示例来重现我将要描述的行为。

所以我enum在一些标题中定义了一些类型,比如说:

types.h

typedef enum MyEnum
{
    First,
    Second
} MyEnum;

枚举是一个C枚举,因为该项目是 ABI 安全的,并且 API 是 C 函数和类型的薄层(我们对沙漏模式的实现)

它还有两个处理打印的函数,假设这些是函数(实际上只有函数的主体不同):

inline std::ostream & operator << (std::ostream & out, MyEnum value) 
{ 
    return out << get_string(value);
} 

types.cpp中,我有:

namespace MyNamespace
{
    const char* get_string(MyEnum value)
    {
        assert(0);
    }
}

如果我在我的代码中调用这样的东西

MyEnum x = First;
std::stringstream os;
os << "Value of x is: " << x;

函数中的assert(0)get_string()将被触发。

但是如果我打电话给记录器:

LOG_INFO("Value of x is: " << x);

出于某种原因,在 Visual Studio(2017 如果重要)中,当调用记录器的内部流成员(也是类型std::stringstream)时,x它会调用<ostream>函数:_Myt& __CLR_OR_THIS_CALL operator<<(int _Val),即它将枚举视为整数,并将值打印为一个数字,而不是使用我的运算符重载。

但是,在 Linux 中 - 用 编译的相同代码gcc 5.4.0调用 myoperator<<并触发断言。

我真的不知道从哪里开始才能理解这一点......

所以真正的问题是 - 什么会导致编译器\操作系统之间存在这种差异?我从哪里开始调试它?或者如果有人知道是什么原因造成的,我很想知道。

编辑:

LOG_INFO是最终调用的日志基础设施的宏: m_logger->stream() << msg;wherem_logger->stream()返回std::stringstream&并且msg是模板化的值参数,在我的示例中是x

4

0 回答 0