Il semble qu'un constructeur qui prend une référence non-const dans un istream ne puisse pas être construit avec une valeur temporaire dans C++.Référence d'istream temporaire non-const dans le constructeur (C++)
#include <iostream>
#include <sstream>
using namespace std;
class Bar
{
public:
explicit Bar(std::istream& is) {}
};
int main()
{
istringstream stream1("bar1");
Bar bar1(stream1); // OK on all platforms
// compile error on linux, Mac gcc; OK on Windows MSVC
Bar bar2(istringstream("bar2"));
return 0;
}
Cela compile 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::istringstream)’
test.cpp:9: note: candidates are: Bar::Bar(std::istream&)
test.cpp:7: note: Bar::Bar(const Bar&)
Y at-il quelque chose philosophiquement mal avec la deuxième voie (bar2) de construire un objet Bar? Il me semble plus agréable, et ne nécessite pas cette variable stream1 qui est seulement nécessaire pour un moment.
EDIT: En réponse au commentaire de Johannes Schaub, je voudrais donner un peu plus de contexte. Premièrement, ce n'est pas la première fois que je suis ennuyé par ce comportement du C++, donc je m'intéresse vraiment à la discussion philosophique de haut niveau sur ce sujet. Cela dit, dans ce cas particulier, j'ai une classe qui lit dans un fichier qui contient des données utilisées pour construire l'objet. J'aime aussi écrire des tests automatisés qui utilisent une chaîne à la place du fichier. Mais l'utilisation du fichier pour la construction est le principal cas d'utilisation. J'ai donc décidé de faire un constructeur qui prend un istream, donc je pourrais utiliser soit un fichier (stream), soit une chaîne (stream). C'est comme ça que je suis arrivé ici. Mes programmes de test construisent des objets directement à partir de chaînes, pour simuler la lecture de fichiers. Cela m'évite de créer des fichiers de données séparés pour chaque petit test.
Vous pouvez passer 'istringstream (" bar2 "). Seekg (0)' comme solution de contournement. –
Le comportement MSVC est une extension non standard qui génère un avertissement, et je pense que si vous activez le mode standard (/ Za), vous y trouverez également une erreur. –
@Johannes Schaub: Très intelligent. Je suppose que toute méthode qui renvoie une référence à l'objet temporaire fonctionnerait ici. –