【问题标题】:How to overload the ostream operator << to make it work with log4cxx in C++?如何重载 ostream 运算符 << 以使其与 C++ 中的 log4cxx 一起使用?
【发布时间】:2011-05-13 10:58:54
【问题描述】:

假设我有一个 A 类和一个运算符

// A.h
class A
{
    // A stuff
};
std::ostream& operator<<(std::ostream& os, const A& a);

我在其他地方将我的记录器与 A 一起使用:

LoggerPtr logger(LogManager::getLogger("ThisObject"));
A a;
LOG4CXX_INFO(logger, "A: " << a);

编译器抱怨: 二进制 '

这个错误将我带到operator&lt;&lt;的声明:

// messagebuffer.h
template<class V>
std::basic_ostream<char>& operator<<(CharMessageBuffer& os, const V& val) {
    return ((std::basic_ostream<char>&) os) << val;
}

LOG4XX_INFO 宏扩展为:

#define LOG4CXX_INFO(logger, message) { \
    if (logger->isInfoEnabled()) {\
       ::log4cxx::helpers::MessageBuffer oss_; \
       logger->forcedLog(::log4cxx::Level::getInfo(), oss_.str(oss_ << message), LOG4CXX_LOCATION); }}

MessageBuffer 也“定义”了这个运算符:

// messagebuffer.h
template<class V>
std::ostream& operator<<(MessageBuffer& os, const V& val) {
    return ((std::ostream&) os) << val;
}

我不明白如何以正确的方式重载此运算符以使其工作。有什么想法吗?

【问题讨论】:

  • @Alan Stokes:我正在使用 Visual Studio 2010
  • 尝试在 messagebuffer.h 之前包含 A.h
  • @Juraj Blaho:你认为为什么会这样?在编译器执行它的查找时,我的操作符被完美地定义和知道了。
  • @mister 为什么:错误消息表明它不知道/不可见。
  • @Juraj Blaho:确实如此,但我认为这与错误指向一个特殊的operator&lt;&lt; 的事实有关,该CharMessageBuffer 采用CharMessageBuffer 而不是ostream。我不想在我的类中引入 log4cxx 实现依赖。

标签: c++ operator-overloading log4cxx


【解决方案1】:

您可以尝试在命名空间 std 中声明您的运算符

namespace std {
   ostream& operator<<(ostream& os, const A& a);
}

【讨论】:

  • 我不习惯污染一个不属于我的命名空间,但我应该承认这就像一个魅力!干杯。
  • 我有兴趣了解为什么编译器在这种情况下找不到我的运算符。
  • 我也是!我认为 ADL(依赖于参数的查找)应该使您的代码正常工作;但 ADL 充满了微妙之处,Visual Studio 也添​​加了自己的特质。命名空间 std 技巧以前对我有用。一旦你习惯了,它并不像看起来那么糟糕。
  • 只有在最近的封闭命名空间中没有匹配项时才考虑 ADL。阅读this时,我学到了很多。
【解决方案2】:

Alan 建议将用户定义的运算符放在 std 命名空间中有效。但我更喜欢将用户定义的运算符放在log4cxx::helpers 命名空间中,这也可以。具体来说,

namespace log4cxx { namespace helpers {
    ostream& operator<<(ostream& os, const A& a);
} }

【讨论】:

    【解决方案3】:

    我现在没有可用的编译器,但我认为问题是由于尝试在常量字符串上使用插入运算符引起的。 "A: " &lt;&lt; a

    【讨论】:

    • 我没有插入常量字符串;你一定误读了LOG4CXX_INFO 扩展。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-02-05
    • 1970-01-01
    • 2020-02-10
    • 1970-01-01
    • 1970-01-01
    • 2021-02-12
    • 2011-08-31
    相关资源
    最近更新 更多