【问题标题】:How do I define an overloaded operator outside of a class template? [duplicate]如何在类模板之外定义重载运算符? [复制]
【发布时间】:2021-03-11 09:37:55
【问题描述】:

我想在我的模板类中重载

using namespace std;

template <class T> class Child {

    public:
        
    friend ostream &operator << (ostream &Output, const Child &Object);

};

// What can I change to make my code work?
ostream &operator << (ostream &Output, const Child <T> &Object) {

}

如您所见,我不知道正确的语法是什么,这样我的代码才能正常运行。我的 C++ 书没有这么深入。这真的让我很沮丧,所以我会很感激任何帮助。谢谢你:)

【问题讨论】:

  • 我认为你需要read this answer。根据该答案,我建议您全部研究它们,但最终考虑选项(3)。

标签: c++ class templates operator-overloading


【解决方案1】:

如果您要让它接受模板类型 (const Child&lt;T&gt; &amp;Object),它必须是函数模板。所以试试:

template <class T>
std::ostream &operator << (std::ostream &Output, const Child<T> &Object)
{ ... }

这应该会让你走得更远。

【讨论】:

    【解决方案2】:

    最干净的方法是:

    template <class T>
    class Child {
       void print(std::ostream& os)const;
    public:       
      friend std::ostream &operator << (std::ostream &Output, const Child &Object){
        Object.print(Output);
        return Output;
      }
    };
    // implement Child<T>::print here
    

    朋友运算符中的“胶水”内联的最小量,转发到带有肉的传统方法。

    这使得语法对读者来说显而易见,而且我发现模板的非模板朋友比其他替代方案更理智(例如模板类型的模板朋友)。

    【讨论】:

      【解决方案3】:

      首先,由于类模板通常需要在标头中定义(以便从多个源文件中有效地使用它们)删除using namespace std 并将ostream 引用为std::ostream。快速搜索会发现很多解释为什么最好在头文件中避免使用 using 指令(如 using namespace std)。

      这意味着将类定义更改为

      template <class T> class Child
      {
      
          public:
          
          friend std::ostream &operator << (std::ostream &Output, const Child &Object);
      
      };
      

      函数的定义(在类定义之外)可以更改为

      template<class T> std::ostream &operator << (std::ostream &Output, const Child <T> &Object)
      {
            // presumably operations that stream members of Object to Output in some way
      
            return Output;
      }
      

      【讨论】:

      • 我收到一条警告,上面写着“警告:朋友声明 'std::ostream& operator&)' 声明了一个非模板函数 [-Wnon -template-friend]”我不太清楚如何从这里开始。如何摆脱警告?
      • 您提供的代码不引用Child&lt;U&gt;。我提供的代码示例也没有。如果没有关于 your 代码引用 Child&lt;U&gt; 的上下文的信息,就无法猜测您收到该警告的原因。无论你做了什么,都与我描述的方法不一致。
      猜你喜欢
      • 2012-11-26
      • 2021-09-19
      • 2013-03-21
      • 2016-01-23
      • 2017-08-03
      • 2023-03-13
      • 1970-01-01
      • 2012-11-14
      • 2017-10-29
      相关资源
      最近更新 更多