C++ FAQ 35,16¿Por qué la función de miembro amigo no se reconoce como plantilla de función automáticamente?
http://www.parashift.com/c++-faq-lite/template-friends.html
#include <iostream>
template<typename T>
class Foo {
public:
Foo(T const& value = T());
friend Foo<T> operator+ (const Foo<T>& lhs, const Foo<T>& rhs);
friend std::ostream& operator<< (std::ostream& o, const Foo<T>& x);
private:
T value_;
};
Las reclamaciones Autor:
'El inconveniente que ocurre cuando el compilador ve las líneas amigo hacia arriba en la definición de clase adecuada. En ese momento, aún no sabe que las funciones de amigo son en sí mismas plantillas (¿por qué las funciones miembro de la plantilla de clase no son plantilla de función por defecto?); se supone que son los no-templates de esta manera:'
Foo<int> operator+ (const Foo<int>& lhs, const Foo<int>& rhs)
{ ... }
std::ostream& operator<< (std::ostream& o, const Foo<int>& x)
{ ... }
¿Por qué los que no son plantillas anteriores? ¿Estas plantillas no son instanciadas a través de int?
'Cuando se llama a los < < funciones de operador + o del operador, este supuesto hace que el compilador para generar una llamada a las funciones que no son de plantilla, pero el enlazador le dará un error 'indefinido externa' porque nunca se define realmente esas funciones sin plantilla. '
De hecho, para hacer compilador reconoce lo anterior como plantilla de función, el programador tiene que hacer esto de manera explícita, como a continuación:
template<typename T> class Foo; // pre-declare the template class itself
template<typename T> Foo<T> operator+ (const Foo<T>& lhs, const Foo<T>& rhs);
template<typename T> std::ostream& operator<< (std::ostream& o, const Foo<T>& x);
Podría alguien explicar? Encuentro esto bastante molesto y no sé por qué el compilador no solo crea una instancia de Class Foo reemplazando T por 'int', y lo llama un día.
Gracias.
Entiendo algunas, pero no todas. Con 'amigo Foo operador + (const Foo & lhs, const Foo & rhs);' a lo largo, lo que compilará? ese operador + será una función amiga de Foo, y nada más en el tipo de retorno, parámetro de función, etc., hasta un avance declaración del operador + se encuentra? –
user1559625
@ user1559625 el compilador ve, para cualquier 'T' particular, que 'Foo operador + (const Foo & lhs, const Foo & rhs);' será un amigo si está definido. Además, si ya se ha declarado una plantilla adecuada, luego se creará una instancia. –
ecatmur
Corrección; la sintaxis es diferente para especificar una plantilla para creación de instancias (los corchetes angulares adicionales). – ecatmur