处理我没有启动的项目,我想在类中添加<<
运算符。问题:该类是另一个类的私有内部类,后者位于namespace
。
我做不到。
可以通过这种方式简化问题:
#include <iostream>
#include <map>
namespace A {
class B {
private:
typedef std::map<int, int> C;
C a;
friend std::ostream& operator<<(std::ostream& os, const C &c) {
for (C::const_iterator p = c.begin(); p != c.end(); ++p)
os << (p->first) << "->" << (p->second) << " ";
return os;
}
public:
B() {
a[13] = 10;
std::cout << a << std::endl;
}
};
}
int main() {
A::B c;
}
我尝试使用g++ test.cpp
编译它:error: no match for ‘operator<<’
。编译器找不到我的重载函数。我认为在标题中定义它会更简单,没有运气。如果您认为它更合适,我也可以在CPP文件中定义该类,但我不知道该怎么做。
最后一项要求,我不能使用C ++ 11(不幸的是)。
答案 0 :(得分:8)
由于友元运算符首先在类中声明,因此它只能通过依赖于参数的查找来实现。但是,它的参数类型都不在namespace A
中,因此无法找到。 C
是std::map
的别名,因此出于ADL的目的被视为namespace std
。
有多种方法可以修复它,但没有一种方法是完美的:
namespace A
中的函数;然后它通过正常查找变得可用,而不仅仅是ADL。但是,这会在一定程度上打破封装,如果其他任何事情试图为operator<<
重载std::map
,可能会导致问题。C
声明为内部类,而不是std::map
的别名。这样可以在不破坏封装的情况下启用ADL,但如果您希望它的行为与std::map
类似,则会有点尴尬。答案 1 :(得分:1)
根据Mike Seymour的回答,这是第一个解决方案的示例。 注意运算符&lt;&lt;()应该在B类之外定义,并且暴露B :: C的实数类型。它不完美但可读......
namespace A {
// It has to expose the B::C's type
std::ostream& operator<<(std::ostream& os, const std::map<int, int> &c);
class B {
private:
typedef std::map<int, int> C;
C a;
friend std::ostream& operator<<(std::ostream& os, const B::C &c);
public:
B() {
a[13] = 10;
std::cout << a << std::endl;
}
};
std::ostream& operator<<(std::ostream& os, const B::C &c) {
for (B::C::const_iterator p = c.begin(); p != c.end(); ++p) {
os << (p->first) << "->" << (p->second) << " ";
}
return os;
}
}