2010-11-12 45 views
0

g ++ 4.4.5Résolution d'opérateur surchargé C++

J'ai une classe qui étend la classe std :: ofstream pour ajouter une fonctionnalité.

MyStream& MyStream::operator<<(const bool& val) { 
    if(this->pos == 8) { 
    this->pos = 0; 
    ofstream::operator<<(this->curbyte); //call the parent method 
    } 
    curbyte = curbyte + (val << pos++); 
    return *(this); 
} 

qui vous permet essentiellement d'écrire des bits individuels comme bools puis il va écrire chaque série de 8 en utilisant la méthode mère < <. Je devais utiliser cette syntaxe d'appel ici parce que j'appelle la méthode de base, mais dans ma principale méthode réelle où j'utilise cette classe j'ai essayé d'appeler la ligne suivante:

bout << (unsigned char) 255u; 

que je veux avoir appeler le < < méthode déjà définie pour ofstream et unsigned char mais elle me donne une longue erreur de surcharge ambiguë listant tous les candidats liés à char déjà définis pour ofstream (char, unsigned char, signed char) et ma propre méthode bool, même si j'ai explicitement cast en char. Cependant, j'ai réussi à le faire fonctionner avec les éléments suivants:

bout.operator<<((unsigned char) 255u); 

Cela doit avoir quelque chose à voir avec la façon dont g ++ la coulée implicite (je suppose qu'il ya un casting plus possible après mon casting défini par l'utilisateur dans la premier cas qui le rend ambigu que la syntaxe d'appel de fonction évite). Est-ce que quelqu'un sait exactement pourquoi cela se produit ou s'il y a une meilleure syntaxe qui évite l'erreur?

+0

Je suis surpris que 'bout.operator << ((unsigned char) 255u)' fonctionne. Pouvez-vous confirmer quelle fonction il appelle réellement? –

+0

Est-ce que vous avez un 'using ofstream :: operator <<;' sTatEmEnt dans MyStream? (remarqué que vous aimez camelcase) ;-) –

+0

@Charles Bailey: la différence ne peut provenir que du préfixe 'bout.' qui supprime les correspondances' :: operator << 'de la résolution. Je suppose qu'il correspond à celui ci-dessus, parce que c'est le seul exposé directement par MyStream, avec les autres ne faisant que correspondre après que MyStream est tombé dans un ofstream & for :: operator <<. –

Répondre

5

Les operator<< de std::ostream définis comme des fonctions membres ne sont pas virtual. Votre operator<< masque toutes les versions de la classe de base de cette fonction afin qu'elles ne soient pas visibles pour la résolution de surcharge. Cependant, les operator<< qui sont définies comme des fonctions libres sont visibles.

Le operator<< qui prennent char, unsigned char et signed char sont toutes les fonctions libres.

Cela signifie que dans bout << (unsigned char) 255u votre fonction membre et la fonction libre prenant un unsigned char sont tous deux visibles pour la résolution de surcharge.

Pour appeler la fonction libre en prenant un unsigned char, votre instance de classe doit être liée à une référence à une classe de base, ce qui compte comme une «conversion» mais le côté droit ne nécessite aucune conversion. Pour appeler votre fonction de membre, le unsigned char doit être converti en bool - à nouveau une 'Conversion' mais le côté gauche ne nécessite aucune conversion. Aucune de ces séquences de conversion n'est meilleure que l'autre, donc l'appel est ambigu.

2

Il s'agit d'une erreur courante pour les personnes qui sont nouvelles dans les iostreams, c'est-à-dire dériver un nouveau type de flux car vous voulez sortir les données d'une manière différente.

Vous ne pouvez pas non plus ajouter vos propres manipulations, c'est-à-dire que vous ne pouvez pas étendre iomanip.

La bonne façon de données de sortie dans un format différent est de mettre une enveloppe autour des données que vous souhaitez afficher:

ostream& os << my_formatter(t); 

pour différents types de t.

Vous pouvez alors utiliser my_formatter comme une fonction de modèle qui renvoie simplement t, à moins qu'elle ne soit spécialisée. Vous pouvez également lui donner plusieurs arguments.(Elle renverrait une classe contenant une référence aux données sous-jacentes et aurait un opérateur < < surchargé).