This is the mail archive of the
gcc-help@gcc.gnu.org
mailing list for the GCC project.
Re: error: no matching function for call to `Anton::Anton(Anton)`
> 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