C ++定义<<内层阶级的经营者 [英] C++ Defining the << operator of an inner class
问题描述
在我没有启动的项目上工作,我想在类中添加<<
运算符.问题:该类是另一个类的私有内部类,后者在namespace
中.
Working on a project I did not initiate, I want to add an <<
operator to a class. Problem: the class is a private inner class of an other class, the latter being in a namespace
.
我做不到.
可以通过以下方式简化问题:
The problem can be simplified this way:
#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文件中定义该类,但我不知道该怎么做.
I try to compile it with g++ test.cpp
: error: no match for ‘operator<<’
. The compiler did not find my overloaded function. I thought it would have been simpler to define it in the header, with no luck. If you think it is more appropriate, I could also define the class in the CPP file, but I do not know how to do.
最后一个要求,我不能使用C ++ 11.
Last requirement, I cannot use C++11 (unfortunately).
推荐答案
由于在类中首先声明了Friend运算符,因此只能通过依赖于参数的查找来使用它.但是,它的两个参数类型都不在namespace A
中,因此将找不到它. C
是std::map
的别名,因此出于ADL的目的被认为在namespace std
中.
Since the friend operator is first declared inside the class, it's only available by argument-dependent lookup. However, neither of its parameter types are in namespace A
, so it won't be found. C
is an alias for std::map
, so is considered to be in namespace std
for the purposes of ADL.
您可以通过多种方法来解决它,但没有一种是完美的:
There are various ways you could fix it, none of which are perfect:
- 在类定义之前在
namespace A
中声明函数;那么它就可以通过常规查询使用,而不仅仅是ADL.但是,这在某种程度上破坏了封装,如果其他任何尝试使operator<<
重载为std::map
,则可能会引起问题. - 用命名的静态(而非朋友)函数代替运算符重载,并按名称进行调用.
- 将
C
声明为内部类,而不是std::map
的别名.这样可以在不破坏封装的情况下启用ADL,但是如果您希望它的行为像std::map
一样,则有点尴尬.
- Declare the function in
namespace A
before the class definition; then it becomes available by normal lookup, not just ADL. However, this breaks the encapsulation somewhat, and might cause problems if anything else tries to overloadoperator<<
forstd::map
. - Replace the operator overload with a named static (not friend) function, and call it by name.
- Declare
C
as an inner class, rather than an alias forstd::map
. This enables ADL without breaking encapsulation, but is a bit awkward if you want it to behave just likestd::map
.
这篇关于C ++定义<<内层阶级的经营者的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!