J'écris une petite bibliothèque matricielle en C ++ pour les opérations matricielles. Cependant, mon compilateur se plaint, alors que ce n'était pas le cas auparavant. Ce code a été laissé sur une étagère pendant 6 mois et entre les deux, j'ai mis à niveau mon ordinateur de debian etch à lenny (g ++ (Debian 4.3.2-1.1) 4.3.2) mais j'ai le même problème sur un système Ubuntu avec le même g ++ .
Voici la partie pertinente de ma classe de matrice:
namespace Math
{
class Matrix
{
public:
[...]
friend std::ostream& operator<< (std::ostream& stream, const Matrix& matrix);
}
}
Et la "mise en œuvre":
using namespace Math;
std::ostream& Matrix::operator <<(std::ostream& stream, const Matrix& matrix) {
[...]
}
C'est l'erreur donnée par le compilateur:
matrix.cpp: 459: erreur: 'std :: ostream & Math :: Matrix :: operator << (std :: ostream &, const Math :: Matrix &)' doit prendre exactement un argument
Je suis un peu confus par cette erreur, mais là encore, mon C ++ est devenu un peu rouillé après avoir fait beaucoup de Java ces 6 mois. :-)
la source
operator<<
doit-il être dans l'espace de noms deMath
? Il semble que cela devrait être dans l'espace de noms global. Je suis d'accord que mon compilateur veut que ce soit dans l'espace de noms deMath
, mais cela n'a pas de sens pour moi.Je vous parle simplement d'une autre possibilité: j'aime utiliser les définitions d'amis pour cela:
La fonction sera automatiquement ciblée dans l'espace de noms environnant
Math
(même si sa définition apparaît dans le cadre de cette classe) mais ne sera visible que si vous appelez l'opérateur << avec un objet Matrix qui rendra la recherche dépendante de l'argument trouver cette définition d'opérateur. Cela peut parfois aider avec des appels ambigus, car il est invisible pour les types d'arguments autres que Matrix. Lors de l'écriture de sa définition, vous pouvez également vous référer directement aux noms définis dans Matrix et à Matrix lui-même, sans qualifier le nom avec un préfixe éventuellement long et fournir des paramètres de modèle commeMath::Matrix<TypeA, N>
.la source
Pour ajouter à la réponse de Mehrdad,
Dans votre implémentation
la source
En supposant que nous parlons de surcharge
operator <<
pour toutes les classes dérivées destd::ostream
pour gérer laMatrix
classe (et non de surcharge<<
pourMatrix
classe), il est plus logique de déclarer la fonction de surcharge en dehors de l'espace de noms Math dans l'en-tête.Utilisez une fonction ami uniquement si la fonctionnalité ne peut pas être obtenue via les interfaces publiques.
Matrix.h
Notez que la surcharge de l'opérateur est déclarée en dehors de l'espace de noms.
Matrix.cpp
En revanche, si votre fonction de surcharge ne doit être fait un ami : besoins d' accès aux membres privés et protégés.
Math.h
Vous devez entourer la définition de fonction d'un bloc d'espace de noms au lieu de simplement
using namespace Math;
.Matrix.cpp
la source
En C ++ 14, vous pouvez utiliser le modèle suivant pour imprimer tout objet qui a une const T :: print (std :: ostream &); membre.
En C ++ 20, les concepts peuvent être utilisés.
la source
std::ostream&
, puisque c'est le type de retour de toute façon?