Estoy escribiendo una pequeña biblioteca matricial en C ++ para operaciones matriciales. Sin embargo, mi compilador se queja, donde antes no lo hacía. Este código se dejó en un estante durante 6 meses y en el medio actualicé mi computadora de debian etch a lenny (g ++ (Debian 4.3.2-1.1) 4.3.2) sin embargo, tengo el mismo problema en un sistema Ubuntu con el mismo g ++ .
Aquí está la parte relevante de mi clase de matriz:
namespace Math
{
class Matrix
{
public:
[...]
friend std::ostream& operator<< (std::ostream& stream, const Matrix& matrix);
}
}
Y la "implementación":
using namespace Math;
std::ostream& Matrix::operator <<(std::ostream& stream, const Matrix& matrix) {
[...]
}
Este es el error dado por el compilador:
matrix.cpp: 459: error: 'std :: ostream & Math :: Matrix :: operator << (std :: ostream &, const Math :: Matrix &)' debe tomar exactamente un argumento
Estoy un poco confundido por este error, pero nuevamente mi C ++ se ha oxidado un poco después de hacer mucho Java esos 6 meses. :-)
fuente
operator<<
tiene que estar en el espacio de nombres deMath
? Parece que debería estar en el espacio de nombres global. Estoy de acuerdo en que mi compilador quiere que esté en el espacio de nombres deMath
, pero eso no tiene sentido para mí.Solo le cuento sobre otra posibilidad: me gusta usar definiciones de amigos para eso:
La función se dirigirá automáticamente al espacio de nombres circundante
Math
(aunque su definición aparezca dentro del alcance de esa clase) pero no será visible a menos que llame al operador << con un objeto Matrix que hará que la búsqueda dependiente del argumento encuentre esa definición de operador. Eso a veces puede ayudar con llamadas ambiguas, ya que es invisible para los tipos de argumentos distintos de Matrix. Al escribir su definición, también puede referirse directamente a los nombres definidos en Matrix y a la propia Matrix, sin calificar el nombre con algún prefijo posiblemente largo y proporcionar parámetros de plantilla comoMath::Matrix<TypeA, N>
.fuente
Para agregar a la respuesta de Mehrdad,
En su implementación
fuente
Suponiendo que estamos hablando de sobrecargar
operator <<
para todas las clases derivadasstd::ostream
para manejar laMatrix
clase (y no sobrecargar<<
para laMatrix
clase), tiene más sentido declarar la función de sobrecarga fuera del espacio de nombres matemático en el encabezado.Utilice una función amiga solo si la funcionalidad no se puede lograr a través de las interfaces públicas.
Matrix.h
Tenga en cuenta que la sobrecarga del operador se declara fuera del espacio de nombres.
Matrix.cpp
Por otro lado, si su función de sobrecarga no es necesario hacer un amigo es decir, necesita tener acceso a los miembros privados y protegidos.
Math.h
Debe encerrar la definición de la función con un bloque de espacio de nombres en lugar de solo
using namespace Math;
.Matrix.cpp
fuente
En C ++ 14 puede usar la siguiente plantilla para imprimir cualquier objeto que tenga un T :: print (std :: ostream &) const; miembro.
En C ++ 20 se pueden usar conceptos.
fuente
std::ostream&
, ya que es el tipo de retorno de todos modos?