Вопрос по c++, gcc – C ++: объявление друга ‘объявляет не шаблонную функцию

4

У меня проблема с перегрузкой<< оператор потока, и я не нахожу решение:

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;
};

Это выдает следующее сообщение об ошибке:

warning: объявление друга ‘std :: ostream & operator << (std :: ostream &, const NVector &) 'объявляет не шаблонную функцию [-Wnon-template-friend]

error: ‘std :: ostream & NVector :: operator << (std :: ostream &, const NVector &) 'должен принимать ровно один аргумент

Как решить эту проблему?

Большое спасибо

Друг не участник, аoperator<< не должен быть участником. Удалите разрешение в заголовке определения. chris

Ваш Ответ

1   ответ
10

friend объявление (как ясно сказано в предупреждении, может быть, не так понятно для понимания) объявляет одну функцию без шаблонов в качестве друга. То есть когда вы создаете экземпляр шаблонаNVector<int,5> объявляет не шаблонную функциюstd::ostream& operator<<(std::ostream&,NVector<int,5>) как друг. Обратите внимание, что это отличается от объявления функции шаблона, которую вы предоставили в качестве друга.

Я бы порекомендовал вам определить функцию друга внутри определения класса. Вы можете прочитать больше об этом в этомотве.

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

В качестве альтернативы вы можете выбрать другие варианты:

объявитьoperator<< template как друг (предоставит доступ ко всем экземплярам шаблона), объявить конкретный экземпляр этого шаблона как друга (более громоздко писать) или избегать дружбы в целом, предоставляя публикеprint( std::ostream& ) функция-член и вызов ее из нешаблонного шаблонаoperator<<. Я бы все же решил подружиться с не шаблонной функцией и предоставить определение внутри шаблонного класса.

Вторая проблема заключается в том, что когда вы хотите определить оператор вне класса левого аргумента, оператор является бесплатная функция (не привязан к классу) и поэтому не должен быть квалифицирован:

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

Похожие вопросы