首页 > 解决方案 > C++:不能使 operator<< 成为模板嵌套类的朋友

问题描述

这是基本的代码结构(如果它与问题相关,我会透露更多):

class Outer {
    // Forward declaration for the next forward declaration
    template <class C> class Inner;

    // Forward declaration for the actual Inner class definition
    template <class C>
    friend std::ostream& operator<<(std::ostream &os, const Inner<C> &obj);

    template <class C>
    class Inner {
        friend std::ostream& operator<< <>(std::ostream &os, const Inner &obj);
    };
};

由于内部类是模板化的,我意识到我的operator<<覆盖也必须如此。此外,第二个friend声明是一个模板实例化,所以它operator<< <C>只是与Outer::Inner<C>.

当我在单独的实现文件中定义运算符覆盖时,它看起来像这样:

template <class C>
std::ostream& operator<<(std::ostream &os, const Outer::Inner<C> &obj) {
    // definition
}

在过去的几天里,我一再将我的代码重构到一个荒谬的程度,希望能成功。最近,我尝试只*.h在 g++ 上进行编译,并在同一行(带有模板实例化的那一行)收到了三个错误消息。

outer.h:x:y1: error: declaration of ‘operator<<’ as non-function
    friend std::ostream& operator<< <>(std::ostream &os, const Inner &obj);
                                 ^~
outer.h:x:y1: error: expected ‘;’ at end of member declaration
outer.h:x:y2: error: expected unqualified-id before ‘&lt;’ token
    friend std::ostream& operator<< <>(std::ostream &os, const Inner &obj);
                                    ^

尽管广泛搜索了错误输出中给出的短语,但是,我仍然无法解决这个问题,所以如果有 C++ 经验的人知道他们在做什么,我将不胜感激。

标签: c++templatesinner-classesfriend

解决方案


经过更多研究,我确信这种特定情况实际上是不可能的——operator重载通常不能成为嵌套和模板化类的朋友。(如果您认为这是错误的,请告诉我原因,因为我自己还远不是 C++ 专家。)

我已经尝试了很多很多不同的解决方案,虽然我认为详细说明我尝试过的每种方法以及它们失败的具体原因并不是很有成效,但其中包括一些错误

  • 不完整类型的无效使用class Outer
  • 字段...具有不完整的类型Outer::Inner<[类型]>
  • 不匹配operator<<
  • 模棱两可的过载operator<<

除了原始帖子中的那些。

所以在我的代码的这个领域,我放弃了这种operator<<方法。我不太优雅但立即有效的替代方案:

class Outer {
    template <class C>
    class Inner {
    public:
        std::ostream& printout(std::ostream &os) {
            os << /* whatever */ << /* I want */ << /* to print */;
            return os;
        }
    };
};

一些可能有用的链接:


推荐阅读