更大宏结构的有线输出

wired output of a bigger macro construct

本文关键字:输出 结构      更新时间:2023-10-16

我使用宏来研究日志记录机制:

#define LOGFATAL 1 // very serious errors
#define TOSTRING(s) dynamic_cast< std::ostringstream & >((std::ostringstream() << s ) ).str()
#define LOG_TRANSFER(t, s) "[" << t << "] " << s
void inline print_log(const char *level, const std::string& value)
{
    std::cout << "[" << timestamp() << "]["<< level << "]" << value << std::endl;
}
#ifdef DEBUGGING
    #define DEBUG_OUT(l, s) print_log(l, TOSTRING(s));
#else
    #define DEBUG_OUT(s, l)
#endif

#if DEBUGGING >= LOGFATAL
    #define LOG_FATAL(s)        DEBUG_OUT("FATAL", s)
#else
    #define LOG_FATAL(s)
#endif

我用他的方式:LOG_TRACE(LOG_TRANSFER(ptr,"MemoryManager>allocate")LOG_TRACE("MemoryManager>size:"<<active_list.size())

gcc的作用是:

print_log("TRACE", dynamic_cast< std::ostringstream & >((std::ostringstream() << "[" << ptr << "] " << "MemoryManager > allocate " ) ).str());
print_log("TRACE", dynamic_cast< std::ostringstream & >((std::ostringstream() << "MemoryManager > size : " << active_list.size() ) ).str());

这在我看来还可以,但我得到了以下输出:

[0 s][TRACE]0x80940d40x9988ea8] MemoryManager > allocate 
[0 s][TRACE]0x80941e01

错误在哪里?

问题在于:

dynamic_cast< std::ostringstream & >((std::ostringstream() << s )).str()

或者更准确地说:

std::ostringstream() << s

原因是表达式std::ostringstream()是一个临时对象,您不能在其上调用非成员重载<<,因为所有非成员<<重载都将第一个参数作为std::ostream&,这是非常量引用。但是临时引用不能绑定到非常量引用。因此,当您想要打印char*时,会调用一个成员函数,该函数将转换为void*并打印地址。

你需要做一个小黑客。将临时对象(右值)转换为引用类型(左值)为:

std::ostringstream().flush() << s

我为什么要那样叫flush()

你可以在一个临时对象上调用一个成员函数。我选择flush()是因为它返回std::ostream&,这是一个非常量引用,也是我们所需要的。

它的区别在于:

std::ostringstream() << "nawaz" ; //it prints the address of "nawaz".
std::ostringstream().flush() << "nawaz" ; //it prints "nawaz"

第一个调用打印地址的成员operator<<,第二个调用打印c字符串的非成员operator<<。这就是幕后的不同。

所以试试这个:

dynamic_cast< std::ostringstream & >((std::ostringstream().flush() << s )).str()

这应该行得通。

此外,我建议在这里使用static_cast,正如您已经知道的类型:

static_cast< std::ostringstream & >((std::ostringstream().flush() << s )).str()

它不依赖于RTTI。