Es solo una advertencia sobre un aspecto complicado del idioma. Cuando declara una función friend
, no es miembro de la clase en la que se encuentra la declaración. Puede definirla allí por conveniencia, pero en realidad pertenece al espacio de nombres.
Al declarar una función amiga que no es una plantilla, dentro de una plantilla de clase, todavía se declara una función que no es de plantilla en el espacio de nombres. No es un miembro de la clase ni una plantilla. Sin embargo, es generado por la plantilla de clase.
Generar funciones que no sean de plantilla desde una plantilla es un poco brumoso. Por ejemplo, no puede agregar una declaración para esa función fuera del bloque class
. Por lo tanto, debe definirlo también dentro del bloque class
, lo cual tiene sentido porque la plantilla de clase lo generará.
Otra cosa difícil acerca de los amigos es que la declaración dentro de class Float {}
no declara la función en el espacio de nombres. Solo puede encontrarlo a través de la resolución de sobrecarga de significado dependiente del argumento, es decir, especificando que un argumento tiene el tipo Float
(o una referencia o puntero). Esto no es un problema para operator+
, ya que es probable que se sobrecargue de todos modos, y nunca se llamará a excepción de con tipos definidos por el usuario.
Para un ejemplo de un posible problema, imagine que tiene un constructor de conversión Float::Float(Bignum const&)
. Pero Bignum
no tiene operator+
. (Disculpe, ejemplo inventado.) Usted desea confiar en operator+(Float const&, Float const&)
para Bignum
además. Ahora my_bignum + 3
no se compilará porque ninguno de los operandos es Float
por lo que no puede encontrar la función friend
.
Probablemente, no tiene nada de qué preocuparse, siempre que la función en cuestión sea operator
.
O bien, puede cambiar el friend
para que sea una plantilla también. En ese caso, debe definirse fuera de el bloque class {}
, y declararse antes, en lugar de necesitar declararse y definirse dentro de.
template<int E, int F> // now this is a template!
Float<E, F> operator+ (const Float<E, F> &lhs, const Float<E, F> &rhs);
template<int E, int F>
class Float
{
// deduce arguments E and F - this names operator+< E, F >.
friend Float<E, F> operator+<> (const Float<E, F> &lhs, const Float<E, F> &rhs);
};
Es posible que desee leer http://www.parashift.com/c++-faq-lite/templates.html#faq-35.16 – UncleBens