La fameuse restriction contre les temporaires non-nommés
Au début elle me paraissait arbitraire, mais j'ai enfin trouvé un cas où son absence pouvait être dangereuse: Les fonctions retournant une référence vers les paramètres.
D'un autre côté, g++ autorise à appeler des fonctions membres des temporaires non-nommés, et là ça marche, donc la durée de vie doit être garantie dans ce cas...
Un point intéressant de ce côté est qu'il en est de même pour les opérateurs: Un opérateur membre compilera sans problème là où un opérateur non-membre provoquera une erreur "no match"...
Décidément les auteurs avaient plus de suite dans les idées que moi.
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71
| //
// Test de temporaires non-nommés couplés à l'opérateur d'insertion de flux
// (note: Je suis passé du français à l'anglais sans trop m'en rendre compte par la suite...)
//
#include <iostream>
#include <sstream>
using namespace std;
class pseudostream
{
ostringstream os;
pseudostream(pseudostream const &);
pseudostream& operator=(pseudostream const &);
public:
pseudostream() { cout << "(ctor)"; }
~pseudostream() { cout << "(dtor)"; }
pseudostream& put(char c) { cout << "(put)"; os.put(c); return *this; }
pseudostream& putstring(string const &s) { cout << "(putstring)"; os << s; return *this; }
string str() const { cout << "(str)"; return os.str(); }
//TEST: With internal operators, there is no problem.
pseudostream& operator<<(char const *s)
{
return putstring(s);
}
pseudostream& operator<<(string const &s)
{
return putstring(s);
}//*/
};
/*
//TEST: With external operators: It doesn't match because of the rvalue.
pseudostream& operator<<(pseudostream &os, char const *s)
{
return os.putstring(s);
}
pseudostream& operator<<(pseudostream &os, string const &s)
{
return os.putstring(s);
}//*/
pseudostream& InsertString(pseudostream &os, string const &s)
{
return os << s;
}
int main(void)
{
//Test 1: No ulterior use
pseudostream() << "abc" << "def";
//-->PASS only with internal ops, fails to compile with external.
//Test2: With ulterior use
cout << (pseudostream() << "ghi" ).str() << endl;
//-->PASS only with internal ops, fails to compile with external.
//Test 3: Use a function instead
//cout << InsertString(pseudostream(), "jkl" ).str() << endl;
//-->FAIL
//Test 4: Appel de fonction membre
cout << ( pseudostream().put('m').put('n').put('o') ).str() << endl;
//-->PASS
cin.ignore(numeric_limits<streamsize>::max(), '\n');
return 0;
} |