Подтвердить что ты не робот

Декларация друга объявляет функцию без шаблона

У меня есть базовый класс, похожий на код ниже. Я пытаюсь перегрузить < < < для использования с cout. Однако g++ говорит:

base.h:24: warning: friend declaration ‘std::ostream& operator<<(std::ostream&, Base<T>*)’ declares a non-template function
base.h:24: warning: (if this is not what you intended, make sure the function template has already been declared and add <> after the function name here) -Wno-non-template-friend disables this warning

Я попытался добавить < > after < < в объявлении класса/прототипе. Однако, я получаю его does not match any template declaration. Я пытаюсь полностью определить шаблон оператора (который я хочу), но я только смог заставить его работать со следующим кодом, при этом оператор вручную создавал экземпляр.

base.h

template <typename T>
class Base {
  public:
    friend ostream& operator << (ostream &out, Base<T> *e);
};

base.cpp

ostream& operator<< (ostream &out, Base<int> *e) {
    out << e->data;
return out;
}

Я хочу просто иметь это или подобное в заголовке, base.h:

template <typename T>
class Base {
  public:
    friend ostream& operator << (ostream &out, Base<T> *e);
};

template <typename T>
ostream& operator<< (ostream &out, Base<T> *e) {
    out << e->data;
return out;
}

Я читал в другом месте в Интернете, что размещение < < < < < и() в прототипе должны исправить это, но это не так. Могу ли я получить это в одном шаблоне функции?

4b9b3361

Ответ 1

Похоже, вы хотите изменить:

friend ostream& operator << (ostream& out, const Base<T>& e);

To:

template<class T>
friend ostream& operator << (ostream& out, const Base<T>& e);

Ответ 2

Gcc справедливо предупреждает вас. Несмотря на его появление (он принимает базовый аргумент), он не является шаблоном функции.

У вашего определения класса есть объявление без шаблона функции friend (без шаблона), но определение функции друга позже является шаблоном функции (то есть начинается с шаблона..).

Также ваш оператор < берет Базу *. Это неверно. Он должен быть Base const и сохранять его встроенную семантику

Вероятно, вы смотрите на что-то, как показано ниже:

template <typename T> 
class Base { 
  public: 
    friend ostream& operator << (ostream &out, Base<T> const &e){
       return out;
    }; 
}; 

int main(){
   Base<int> b;
   cout << b;
}

Если вы хотите полностью шаблонов, то это, вероятно, то, что вы хотите. Но я не уверен, насколько это полезно по сравнению с предыдущим. Поскольку поиск включает ADL, вы никогда не сможете разрешить любое условие, когда T не равно U (до тех пор, пока вызов происходит из контекста, не связанного с этим классом, например, из функции "main" )

template <typename T>  
class Base {  
  public:  
    template<class U> friend ostream& operator << (ostream &out, Base<U> const &e){ 
       return out; 
    };  
};

int main(){ 
   Base<int> b; 
   cout << b; 
} 

Ответ 3

Возможно, что вы ищете:

template <typename T>
class Base;

template <typename T>
ostream& operator<< (ostream &, const Base<T>&);

template <typename T>
class Base
{
  public:
    template<>
    friend ostream& operator << <T>(ostream &, const Base<T> &);
};

template <typename T>
ostream& operator<< ( ostream &out, const Base<T>& e )
{
    return out << e->data;
}

У этого пользователя только одно экземпляр шаблона, тот, где параметр шаблона оператора соответствует параметру шаблона класса.

UPDATE: К сожалению, это незаконно. И MSVC, и Comeau отвергают это. В связи с этим возникает вопрос о том, почему исходное сообщение об ошибке предложило довольно точно этот подход.

Ответ 4

изменения

friend ostream& operator << (ostream& out, const Base<T>& e);

к

friend ostream& operator << <T>(ostream& out, const Base<T>& e);

также должен работать - я просто решил идентичную проблему таким образом.

Ответ 5

изменения

friend ostream& operator << (ostream &out, Base<T> *e)`

Для

template<T> friend ostream& operator << (ostream &out, Base *e)

Ответ 6

изменить

ostream& operator<< (ostream &out, Base<int> *e) {
    out << e->data;
    return out;
}

к

ostream& operator<< (ostream &out, T *e) {
    out << e->data;
    return out;
}