declaración de amigo declara una función que no es de plantilla [duplicar]


Esta pregunta ya tiene una respuesta aquí:

Tengo una clase base similar al código de abajo. Estoy intentando sobrecargar

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

He intentado agregar después de does not match any template declaration. He estado tratando de tener la definición del operador completamente templada (que quiero), pero solo he sido capaz de conseguir que funcione con el siguiente código, con el operador instanciado manualmente.

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

Quiero tener esto o similar en el encabezado, 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;
}

He leído en otra parte en línea que poner entre

Author: Chubsdad, 2010-10-28

6 answers

Parece que quieres cambiar:

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

A:

template<class T>
friend ostream& operator << (ostream& out, const Base<T>& e);
 32
Author: Nathan Pitman,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-10-28 05:55:14

Gcc te está advirtiendo correctamente. A pesar de sus apariencias (toma el argumento base), no es una plantilla de función.

Su definición de clase tiene una declaración no-plantilla de la función amigo (sin la plantilla), pero la definición de la función amigo más adelante es una plantilla de función (es decir, comienza con plantilla..).

También su operador

Probablemente usted está mirando algo como abajo:

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

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

Si quieres plantillas completas, entonces esto es probablemente lo que quieres. Pero no estoy seguro de cuán útil es esto sobre el anterior. Dado que la búsqueda implica ADL, nunca podrá resolver a ninguna condición donde T no sea igual a U (siempre y cuando la llamada sea desde un contexto no relacionado con esta clase, por ejemplo, desde la función '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; 
} 
 15
Author: Chubsdad,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-10-28 05:57:58

Probablemente lo que estás buscando es:

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

Esto solo permite una sola instanciación de la plantilla, aquella en la que el parámetro de plantilla del operador coincide con el parámetro de plantilla de la clase.

ACTUALIZACIÓN: Desafortunadamente, es ilegal. Tanto MSVC como Comeau lo rechazan. Lo que plantea la pregunta de por qué el mensaje de error original sugirió casi EXACTAMENTE este enfoque.

 9
Author: Ben Voigt,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-10-28 05:43:41

Cambiando

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

A

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

Debería funcionar también just Acabo de resolver un problema idéntico de esta manera.

 4
Author: Tyrone Hinderson,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-12-13 15:06:32

Cambiando

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

A

template<T> friend ostream& operator << (ostream &out, Base *e)
 0
Author: Elías Arriaga,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-03-04 07:47:20

Cambiar

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

A

ostream& operator<< (ostream &out, T *e) {
    out << e->data;
    return out;
}
 -3
Author: Bruce Armstrong,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-10-28 05:28:05