2009-11-19 3 views
5

J'ai écrit un std::streambuf personnalisé dans le cadre d'un système de journalisation. Cependant, j'ai des problèmes avec le premier morceau de sortie d'un flux qui n'est pas formaté correctement.std :: ostream ne pas formater const char * correctement la première fois qu'il est utilisé

est ici un cas-test réduit qui n'utilise pas de coutume streambuf ou ostream cours:

#include <iostream> 

int main() 
{ 
    std::streambuf *coutbuf = std::cout.rdbuf(); 
    std::ostream(coutbuf) << "test" << ": writing to cout using a separate ostream." << std::endl; 
    return 0; 
} 

Compiler cela en utilisant g ++:

$ g++ --version 
g++ (Ubuntu 4.4.1-4ubuntu8) 4.4.1 

$ g++ -o fail reduced-case.cpp 

$ ./fail 
0x400c80: writing to cout using a separate ostream. 

Notez que la première chaîne littérale («test ") est formaté comme un pointeur générique (l'adresse de la chaîne est sortie en hexadécimal), tandis que la seconde chaîne littérale est formatée correctement. La seule chose que je peux penser est qu'il est invalide d'utiliser directement un std::ostream nouvellement construit comme cela (c'est-à-dire, sans le mettre dans une variable). Si c'est le cas, j'aimerais beaucoup savoir ce qui le rend exactement invalide (je suppose que cela n'a rien à voir avec les iostreams en particulier, mais plutôt avec l'ordre d'évaluation ou les interactions avec les constructeurs ou quelque chose comme ça). Si ce n'est pas le problème, alors qu'est-ce?

Répondre

8

Le problème est que vous ne devez pas écrire dans un objet de flux temporaire. Ce:

std::ostream(coutbuf) << "blah"; 

ne fonctionne pas comme prévu, puisque l'argument à la main gauche pour operator<<() est un rvalue. Cependant, tous les opérateurs surchargées en fonction sans prendre une référence non-const à un flux comme argument de gauche:

std::ostream& operator<<(std::ostream&, ...); 

Depuis rvalues ​​ne se lient pas à des références non-const, ils ne peuvent pas être appelés.

Je soupçonne que votre implémentation std lib implémente << pour const char* en fonction libre et doit donc revenir à une << qui est membre de std::ostream. Il semble dans votre implémentation que celui qui génère un pointeur soit void*. Bottom line: N'essayez pas d'écrire dans des objets de flux temporaires.

1

Vous ne pouvez pas utiliser un objet de flux temporaire comme celui-ci. Donnez un nom à la variable temporaire.

#include <iostream> 

int main() 
{ 
    std::streambuf *coutbuf = std::cout.rdbuf(); 
    std::ostream os(coutbuf); 
    os << "test" << ": writing to cout using a separate ostream." << std::endl; 
    return 0; 
} 
Questions connexes