【问题标题】:C++: Cannot make operator<< a friend of a templated nested classC++:不能使 operator<< 成为模板嵌套类的朋友
【发布时间】:2019-12-21 14:26:13
【问题描述】:

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

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&lt;&lt; 覆盖也必须如此。另外,第二个friend 声明是一个模板实例化,所以operator&lt;&lt; &lt;C&gt; 只是Outer::Inner&lt;C&gt; 的朋友。

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

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

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

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 ‘<’ token
    friend std::ostream& operator<< <>(std::ostream &os, const Inner &obj);
                                    ^

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

【问题讨论】:

  • 在定义中删除 &lt;C&gt; - 这不是有效的语法。此外,模板必须在头文件中定义;编译器需要在使用模板时查看定义。
  • 哦,有趣。我记得在编写内部类的定义时,我必须将template &lt;class C&gt; Outer::Inner&lt;C&gt;::Inner() {/*...*/} 用于构造函数,而将类似的行用于成员函数,所以我一定很困惑(我应该也删除template &lt;class C&gt; 吗?)。此外,我刚刚编译头文件时看到的问题仍然存在。

标签: c++ templates inner-classes friend


【解决方案1】:

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

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

  • 不完整类型的无效使用class Outer
  • 字段...的类型不完整Outer::Inner&lt;[Type]&gt;
  • operator&lt;&lt; 不匹配
  • operator&lt;&lt; 的不明确过载

除了原帖中的那些。

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

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

一些可能有用的链接:

【讨论】:

    猜你喜欢
    • 2011-03-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-08-08
    • 2019-01-29
    • 2011-12-11
    • 2019-03-23
    相关资源
    最近更新 更多