C ++定义<<内层阶级的经营者 [英] C++ Defining the << operator of an inner class

查看:90
本文介绍了C ++定义<<内层阶级的经营者的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在我没有启动的项目上工作,我想在类中添加<<运算符.问题:该类是另一个类的私有内部类,后者在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中,因此将找不到它. Cstd::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 overload operator<< for std::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 for std::map. This enables ADL without breaking encapsulation, but is a bit awkward if you want it to behave just like std::map.

这篇关于C ++定义&lt;&lt;内层阶级的经营者的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆