10

假设我有一个 A 类和一个 operator<< 声明如下:

// 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);

编译器抱怨:二进制 '<<' : no operator found 采用 'const A' 类型的右手操作数(或没有可接受的转换) D:\dev\cpp\lib\apache-log4cxx\log4cxx\包括\log4cxx\helpers\messagebuffer.h 190

此错误将我带到以下声明operator<<

// 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;
}

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

4

3 回答 3

7

您可以尝试在命名空间 std 中声明您的运算符 << (这是合法的,因为您正在传递用户定义类型的实例):

namespace std {
   ostream& operator<<(ostream& os, const A& a);
}
于 2011-05-13T13:45:59.093 回答
2

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

namespace log4cxx { namespace helpers {
    ostream& operator<<(ostream& os, const A& a);
} }
于 2014-01-10T04:42:20.633 回答
0

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

于 2011-05-13T12:15:48.093 回答