C ++:friend declaration'声明一个非模板函数

时间:2012-05-28 16:20:01

标签: c++ templates gcc ostream

我有一个问题是重载<<流操作符而我找不到解决方案:

template<class T, unsigned int TN>
class NVector
{
    inline friend std::ostream& operator<< (
        std::ostream &lhs, const NVector<T, TN> &rhs);
};

template<class T, unsigned int TN>
inline std::ostream& NVector<T, TN>::operator<<(
    std::ostream &lhs, const NVector<T, TN> &rhs)
{
    /* SOMETHING */
    return lhs;
};

它会产生以下错误消息:

  

警告:朋友声明'std :: ostream&amp; operator&lt;&lt;(std :: ostream&amp;,const NVector&amp;)'声明一个非模板函数[-Wnon-template-friend]

     

错误:'std :: ostream&amp; NVector :: operator&lt;&lt;(std :: ostream&amp;,const NVector&amp;)'必须只接受一个参数

如何解决这个问题?

非常感谢。

1 个答案:

答案 0 :(得分:11)

您的代码中存在两个不同的问题,第一个是friend声明(警告清楚地说明,可能不太清楚)可以将单个非模板化函数声明为朋友。也就是说,当您实例化模板NVector<int,5>时,它会将非模板化函数std::ostream& operator<<(std::ostream&,NVector<int,5>)声明为朋友。请注意,这与声明您作为朋友提供的模板功能不同。

我建议你在类定义中定义friend函数。您可以在此answer中详细了解相关内容。

template <typename T, unsigned int TN>
class NVector {
   friend std::ostream& operator<<( std::ostream& o, NVector const & v ) {
      // code goes here
      return o;
   }
};

或者您可以选择其他选项:

  1. operator<<模板声明为朋友(将授予对该模板的任何和所有实例的访问权限),
  2. 将该模板的特定实例化声明为朋友(编写起来比较麻烦)或
  3. 避免友谊完全提供公共print( std::ostream& )成员函数并从模板化的非朋友operator<<调用它。我仍然会选择与非模板函数建立联系,并在模板化类中提供定义。
  4. 第二个问题是当你想在左侧参数的类之外定义一个运算符时,运算符是一个自由函数(没有绑定到一个类),因此它应该不合格:

    template<class T, unsigned int TN>
    inline std::ostream& operator<<(std::ostream &lhs, const NVector<T, TN> &rhs)
    {
        /* SOMETHING */
        return lhs;
    };
    
相关问题