> Don' quite agree with that. But I also don;t have the book in front of me. > > > std::cout << "abc" << "xyz"; > > The result of the first '<<' is NOT a temporary object. It is a reference to the original object no temporary required. Works fine for me. > I was a bit fast here. What I had in mind was to give sort of a typical example where non-const references to temporary objects are used. I came up with classes used to create and output xml-elements to a stream. Works like cout << xml_element("abc").set("field1", "value1").set("field2", "value2"); producing <abc field1="value1" field2="value2> </abc> Here is no need to create a static or an automatic object, a temporary is just fine, created with xml_element("abc"), which then is modified with the set-methods xml_element& xml_element::set(string, string) { ...; return *this; } After processing of the above output-instruction the temporary object is destroyed, and we are happy. And when overloading operator << for xml_elements, we don't need to copy xml_elements, but we can use references (non-const if we wish). (Of course the whole thing is a bit more complicated (but actually not much), since for need to cater for nesting.) Now this structurally is the same as output (or input) streaming like cout << a << b; only in this example the object passed through the references is not a temporary, but a static object. But this is nothing principal: The point here is that it *doesn't matter*, and instead of cout we could use for example a temporary object of type std::ostringstream. For example: std::ostringstream() << "sum = " << 1 + 2 << "\n"; Now since operator << returns a reference to an object of type std::basic_ostream, it seems we can not do much with such a construction (how to get the string out of it??), but with other classes (like xml_element) we can make good use of such constructions. Perhaps in these examples it is a bit confusing, that the reference to the temporary is only used for the hidden "this"-argument, or as second argument of an overloaded << (or for the first argument of << but without good use). So a final example, just to use standard functions: struct Y { int n; Y& set(int new_n) { n = new_n; return *this; } ~Y() { std::cout << "~Y: " << n << "\n"; } }; int f(Y& y) { return y.n++; } int main() { std::cout << f(Y().set(77)) << "\n"; } Output is 77 ~Y: 78 This is all standard conforming (to the best of my knowledge). All clear ?! (Or not???) Oliver > > -----Original Message----- > From: Oliver Kullmann [mailto:O.Kullmann@xxxxxxxxxxxxx] > Sent: Friday, October 10, 2003 2:05 PM > To: gcc-help@xxxxxxxxxxx > Subject: Re: error: no matching function for call to > `Anton::Anton(Anton)` > > > Hi, > > although this thread seems to be closed, it seems necessary to me > to discuss some misunderstandings (as I believe). > > > Hi Eric, > > > > As per section 5.5 of Stroustrup's C++PL (3rd ed or special ed), a temporary object cannot be bound to a non-const reference. > > > > I don't have the book in my office, but it is not true. Temporary object *can* be bound to non-const > references: A typical example is streaming via operator <<, that is, in > > std::cout << "abc" << "xyz"; > > the first call to operator << returns a temporary which is then bound to the > first argument of operator <<, which is a non-const reference. > > Or to give another example (a simplified version of a class for building up xml-expressions): > > #include <iostream> > #include <ostream> > > class Nat { > int n; > public : > Nat() : n(0) {} > Nat& inc() { ++n; } > friend inline std::ostream& operator <<(std::ostream& o, Nat x) { > o << x.n; > } > }; > > int main() { > std::cout << Nat().inc().inc().inc() << "\n"; > } > > This is perfectly legal (and the output is "3"). > > As one finds it in ISO 14882:1998(E), Section 8.5.3, > initialisation of references is not primarily concerned > with constness, but with the distinction between lvalues and > rvalues (every expression is either an lvalue or an rvalue). > The rule about reference binding is as simple (mainly) as follows: > > A non-const reference can be bound only to lvalues, > while a const reference can be bound to lvalues and rvalues. > > Now functions which return references return lvalues > ([ISO], Section 5.2.2, point 10), > while constructors yield rvalues > ([ISO], Section 5.2.3). > > This explains why in the original example of Eric > > Anton a[] = {Anton()}; > > we get an error: only a copy-constructor with a non-const references was > defined, and since the initialisation of the elements of array a happens > via the copy constructor, the copy constructor does not accept the rvalue > Anton(). > > But the member function ref() of Anton defined later yields an lvalue, and > thus > > Anton a[] = {Anton().ref()}; > > is no problem. Just as an illustration: > > #include <iostream> > #include <ostream> > > class Anton { > int n; > public : > explicit Anton(int n) : n(n) {} > Anton(Anton& a) : n(a.n) {} > Anton& ref() { return *this; } > friend inline std::ostream& operator <<(std::ostream& o, Anton a) { > return o << a.n; > } > }; > > int main() { > Anton a[] = {Anton(1).ref(), Anton(0) = Anton(2), Anton(3).ref()}; > std::cout << a[0] << a[1] << a[2] << "\n"; > // output: 123 > } > > I very much recommend (for several reasons) to read > > @Article{Hyslop2002ObjectfulLifetime, > author = {Jim Hyslop}, > title = {Conversations: It's an Object-ful Lifetime}, > journal = {C/C++ Users Journal}, > year = 2002, > volume = 20, > number = 12, > month = {December}, > note = {Can be downloaded from \url{http://www.cuj.com/documents/s=7976/cujcexp2012hyslop/}}, > annote = {Vorhanden. Explizite Typ-Konvertierungen geben R-Werte zurueck, Funktionen, die Referenzen zurueckgeben, aber L-Werte. Bezug zu "It's A Wonderful Life".} > } > > which can be downloaded from the given url, and which discusses the same subject. > > Oliver > >