c++ - uso - Sobrecarga del operador amigo<< para la clase de plantilla
uso correcto de las comillas (3)
Estoy tratando de sobrecargar al operador << como amigo de un par de clase de plantilla, pero sigo recibiendo una advertencia de compilación diciendo
friend declaration std::ostream& operator<<(ostream& out, Pair<T,U>& v) declares a non template function
para este código:
friend ostream& operator<<(ostream&, Pair<T,U>&);
da una segunda advertencia como una recomendación que dice
if this is not what you intended, make sure the function template has already been declared and add <> after the function name here
Aquí está la definición de la función
template <class T, class U>
ostream& operator<<(ostream& out, Pair<T,U>& v)
{
out << v.val1 << " " << v.val2;
}
y aquí está toda la clase.
template <class T, class U>
class Pair{
public:
Pair(T v1, U v2) : val1(v1), val2(v2){}
~Pair(){}
Pair& operator=(const Pair&);
friend ostream& operator<<(ostream&, Pair<T,U>&);
private:
T val1;
U val2;
};
No estaba seguro de qué sacar de la advertencia de recomendación, aparte de que tal vez tengo que poner en algún lugar de la declaración de amigo. ¿Alguien sabe la sintaxis adecuada para esto? Gracias.
Desea hacer que una sola instancia (llamada "especialización" en términos genéricos) de esa plantilla sea un amigo. Lo haces de la siguiente manera
template <class T, class U>
class Pair{
public:
Pair(T v1, U v2) : val1(v1), val2(v2){}
~Pair(){}
Pair& operator=(const Pair&);
friend ostream& operator<< <> (ostream&, Pair<T,U>&);
private:
T val1;
U val2;
};
Debido a que el compilador sabe por la lista de parámetros que los argumentos de la plantilla son T
y U
, no tiene que ponerlos entre <...>
, por lo que pueden dejarse vacíos. Tenga en cuenta que debe colocar una declaración de operator<<
encima de la plantilla de Pair
, como la siguiente:
template <class T, class U> class Pair;
template <class T, class U>
ostream& operator<<(ostream& out, Pair<T,U>& v);
// now the Pair template definition...
Usted declara operador << como devolver un ostream &, pero no hay declaración de devolución en absoluto en el método. Debiera ser:
template <class T, class U>
ostream& operator<<(ostream& out, Pair<T,U>& v)
{
return out << v.val1 << " " << v.val2;
}
Aparte de eso, no tengo problemas ni advertencias para compilar tu código en Visual Studio 2008 con advertencias en el nivel 4. Ah, están los errores del enlazador clásico, pero eso se evita fácilmente moviendo la definición de la función de la plantilla a la declaración de la clase, como se explicó en las preguntas frecuentes de C ++ .
Mi código de prueba:
#include <iostream>
using namespace std;
template <class T, class U>
class Pair{
public:
Pair(T v1, U v2) : val1(v1), val2(v2){}
~Pair(){}
Pair& operator=(const Pair&);
friend ostream& operator<<(ostream& out, Pair<T,U>& v)
{
return out << v.val1 << " " << v.val2;
}
private:
T val1;
U val2;
};
int main() {
Pair<int, int> a(3, 4);
cout << a;
}
Versión en línea simple:
template<typename T> class HasFriend {
private:
T item;
public:
~HasFriend() {}
HasFriend(const T &i) : item(i) {}
friend ostream& operator<<(ostream& os, const HasFriend<T>& x) {
return os << "s(" << sizeof(x) << ").op<<" << x.item << endl;
}
};
Versión revisada de la plantilla:
template<template<typename /**/> class U, typename V>
ostream& operator<<(ostream &os, const U<V> &x) {
return os << "s(" << sizeof(x) << ").op<<" << x.item << endl;
}
template<typename T> class HasFriend {
private:
T item;
public:
~HasFriend() {}
HasFriend(const T &i) : item(i) {}
friend ostream& operator<<<>(ostream&, const HasFriend<T>&);
};