Référence temporaire de stream non const dans le constructeur (C ++)

Il semble qu’un constructeur qui prend une référence non-const à un istream ne puisse pas être construit avec une valeur temporaire en C ++.

#include  #include  using namespace std; class Bar { public: explicit Bar(std::istream& is) {} }; int main() { issortingngstream stream1("bar1"); Bar bar1(stream1); // OK on all platforms // comstack error on linux, Mac gcc; OK on Windows MSVC Bar bar2(issortingngstream("bar2")); return 0; } 

Cela comstack bien avec MSVC, mais pas avec gcc. En utilisant gcc je reçois une erreur de compilation:

 g++ test.cpp -o test test.cpp: In function 'int main()': test.cpp:18: error: no matching function for call to 'Bar::Bar(std::issortingngstream)' test.cpp:9: note: candidates are: Bar::Bar(std::istream&) test.cpp:7: note: Bar::Bar(const Bar&) 

Y a-t-il quelque chose qui ne va pas du sharepoint vue philosophique dans la deuxième manière (bar2) de construire un object Bar? Cela me semble plus agréable et ne nécessite pas cette variable stream1 qui n’est nécessaire que pour un moment.

EDIT : En réponse au commentaire de Johannes Schaub, j’aimerais donner un peu plus de contexte. Premièrement, ce n’est pas la première fois que ce comportement de C ++ m’agace, je suis donc véritablement intéressé par la discussion philosophique de haut niveau sur cette question. Cela dit, dans ce cas particulier, j’ai une classe qui lit dans un fichier contenant des données utilisées pour construire l’object. J’aime aussi écrire des tests automatisés qui utilisent une chaîne au lieu du fichier. Mais l’utilisation du fichier pour la construction est le principal cas d’utilisation. J’ai donc décidé de créer un constructeur prenant un istream afin de pouvoir utiliser un fichier (stream) ou une chaîne (stream). C’est comme ça que je suis arrivé ici. Mes programmes de test construisent des objects directement à partir de chaînes, pour simuler la lecture de fichiers. Cela me évite de créer des fichiers de données distincts pour chaque petit test.

C ++ fonctionne actuellement comme ceci: vous ne pouvez pas lier des références non const à des objects temporaires. MSVC est non standard en permettant cela.

C ++ 0x aura des références de valeur r et changera un peu les choses ici. Il existe diverses interprétations philosophiques que les gens ont essayé d’appliquer – des deux côtés de la question – mais je n’en ai trouvé aucune qui soit tout à fait convaincante. Il semble plus que “vous devez simplement choisir un comportement et vous y tenir”, ce qui explique les modifications actuelles du C ++ et de 0x: le comportement choisi a changé.

Roger a raison… C’est une politique générique de C ++ selon laquelle seules les références const peuvent se lier à des temporaires. Cependant, je ne pense pas que les références rvalue vous aideraient, car vous souhaitez continuer à utiliser un stream non temporaire en utilisant son état modifié.

Plus istream &operator>>(istream &s, Bar &b) , pourquoi ne pas remplacer le constructeur par un friend extracteur istream &operator>>(istream &s, Bar &b) ? Au prix d’append un état non initialisé à l’object, la syntaxe serait encore plus C ++ – ish.