Estou escrevendo uma pequena biblioteca de matrizes em C ++ para operações de matriz. No entanto, meu compilador reclama, onde antes não o fazia. Este código foi deixado em uma prateleira por 6 meses e entrei atualizei meu computador do debian etch para o lenny (g ++ (Debian 4.3.2-1.1) 4.3.2), no entanto, tenho o mesmo problema em um sistema Ubuntu com o mesmo g ++ .
Aqui está a parte relevante da minha classe de matriz:
namespace Math
{
class Matrix
{
public:
[...]
friend std::ostream& operator<< (std::ostream& stream, const Matrix& matrix);
}
}
E a "implementação":
using namespace Math;
std::ostream& Matrix::operator <<(std::ostream& stream, const Matrix& matrix) {
[...]
}
Este é o erro fornecido pelo compilador:
matrix.cpp: 459: erro: 'std :: ostream & Math :: Matrix :: operator << (std :: ostream &, const Math :: Matrix &)' deve ter exatamente um argumento
Estou um pouco confuso com esse erro, mas, novamente, meu C ++ ficou um pouco enferrujado depois de fazer muito Java nesses 6 meses. :-)
fonte
operator<<
tem que estar no espaço para nome deMath
? Parece que deveria estar no espaço de nomes global. Concordo que meu compilador deseja que ele esteja no espaço de nomes deMath
, mas isso não faz sentido para mim.Apenas falando sobre uma outra possibilidade: eu gosto de usar definições de amigos para isso:
A função será automaticamente direcionada para o espaço para nome circundante
Math
(mesmo que sua definição apareça no escopo dessa classe), mas não estará visível a menos que você chame o operador << com um objeto Matrix que fará com que a pesquisa dependente de argumento encontre essa definição de operador. Às vezes, isso pode ajudar com chamadas ambíguas, pois é invisível para outros tipos de argumento que não sejam Matrix. Ao escrever sua definição, você também pode se referir diretamente aos nomes definidos em Matrix e à própria Matrix, sem qualificar o nome com algum prefixo possivelmente longo e fornecer parâmetros de modelo comoMath::Matrix<TypeA, N>
.fonte
Para adicionar à resposta Mehrdad,
Na sua implementação
fonte
Supondo que estamos falando de sobrecarga
operator <<
para todas as classes derivadasstd::ostream
para manipular aMatrix
classe (e não sobrecarregar<<
paraMatrix
classe), faz mais sentido declarar a função de sobrecarga fora do espaço de nomes Math no cabeçalho.Use uma função de amigo apenas se a funcionalidade não puder ser alcançada através das interfaces públicas.
Matrix.h
Observe que a sobrecarga do operador é declarada fora do espaço para nome.
Matrix.cpp
Por outro lado, se sua função de sobrecarga não precisam ser feitas para um amigo ou seja, precisa de acesso a membros privados e protegidos.
Math.h
Você precisa incluir a definição da função com um bloco de espaço para nome em vez de apenas
using namespace Math;
.Matrix.cpp
fonte
No C ++ 14, você pode usar o seguinte modelo para imprimir qualquer objeto que tenha uma const T :: print (std :: ostream &); membro.
No C ++ 20 podem ser utilizados conceitos.
fonte
std::ostream&
, já que é o tipo de retorno?