> Hi Oliver, > > >the first call to operator << returns a temporary which is then bound to the first argument of operator <<, which is a non-const reference. > > That is incorrect. The first call to operator << returns a non-const reference; it does not return a temporary. > of course (I wrote things up yesterday slightly in a hurry); what I meant was to give a potential example for *using* references to non-const temporary objects, and streaming is a potential candidate for showing such a usage, in case the "ground" object is a temporary --- now in case of output to cout we actually get a reference to a static object, but this object could as well be a temporary object, as shown with the class Nat. > >>> example > class Nat { > int n; > public : > Nat() : n(0) {} > Nat& inc() { ++n; } > friend inline std::ostream& operator <<(std::ostream& o, Nat x) { > o << x.n; > } > }; > <<< > > Both the inc() method and the operator << methods are malformed. > of course (as I said, I was a bit fast) (by the way, since I'm developing a generic library, useless warnings are cluttering up the output, so now by default all warnings are off, and so in the above cases I didn't see the missing return statements; the warning system of gcc doesn't seem to be up to the task of what generic programming asks for) > The inc() method should be: > Nat& inc() > { > ++n; > return *this; > } > > That's NOT returning a non-const reference to a temporary. > > That method is malformed. It fails to return a std::ostream reference. It should be: > friend inline std::ostream& operator << (std::ostream& o, Nat const& x) > { > o << x.n; > return *this; > } > > That's NOT returning a non-const reference to a temporary. > including the overloaded << operator was just done for having a nicer output; whether the reference is to a temporary object or not just depends on the circumstances. But an important point here is, that is DOESN'T MATTER: Whether it's a temporary object or not the reference refers to is ignored by the compiler. The return value of operator << is just an lvalue, and that's it. > >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 > > I am aware of that. I figured that Eric may have access to Stroustrup's C++PL, but not (perhaps) to ISO 14882. The 14882 specification isn't light reading. Stroustrup's explanation doesn't delve into the details of lvalues and rvalues in Eric's situation. > but, nevertheless, lvalue and rvalue are more to the heart of the matter; > >Anton a[] = {Anton().ref()}; > > I suspect Eric's original definition of the class without the Anton(Anton const&) copy constructor underlies a flaw in the design of the class. When a programmer jumps through hoops to circumnavigate the compiler from telling him that he's doing something wrong, I get suspicious. sure, there are always the two sides: the general patterns of usage, and the language definition; and since the general usage patterns have been covered, I wanted to add the underlying language issues. Oliver