Passing return value by reference

Discussion in 'C++' started by red floyd, Jun 11, 2004.

  1. red floyd

    red floyd Guest

    Once again, I'm fighting a port from the (allegedly standard compliant)
    VC7.1 to G++.

    VC compiles this, G++ doesn't.

    Am I allowed to pass the anonymous temporary returned by f() to a
    function requiring a non-const reference? I suspect G++ is correct, and
    VC is (again) braindead.


    class A
    {
    public:
    A() { }
    A(const A&) { }
    ~A() { }
    };

    A& operator<<(A& a, const char* p)
    {
    return a;
    }

    A f()
    {
    return A();
    }

    int main()
    {
    f() << "Hello";
    return 0;
    }
    red floyd, Jun 11, 2004
    #1
    1. Advertising

  2. red floyd wrote:
    > ...
    > Am I allowed to pass the anonymous temporary returned by f() to a
    > function requiring a non-const reference?


    No.

    > I suspect G++ is correct, and VC is (again) braindead.


    VC supports this as an extension. The only reason it compiles on VC is
    that you have this extension enabled. Disable it and VC will also issue
    an error message.

    > class A
    > {
    > public:
    > A() { }
    > A(const A&) { }
    > ~A() { }
    > };
    >
    > A& operator<<(A& a, const char* p)
    > {
    > return a;
    > }
    >
    > A f()
    > {
    > return A();
    > }
    >
    > int main()
    > {
    > f() << "Hello";
    > return 0;
    > }


    You can make this compile by implementing 'operator<<' as a member
    function of class 'A'. There's certain asymmetry in C++ behavior when it
    comes to things like this...

    --
    Best regards,
    Andrey Tarasevich
    Andrey Tarasevich, Jun 11, 2004
    #2
    1. Advertising

  3. On Fri, 11 Jun 2004 11:24:13 -0700, Andrey Tarasevich
    <> wrote:

    >red floyd wrote:
    >> ...
    >> Am I allowed to pass the anonymous temporary returned by f() to a
    >> function requiring a non-const reference?

    >
    >No.
    >
    >> I suspect G++ is correct, and VC is (again) braindead.

    >
    >VC supports this as an extension. The only reason it compiles on VC is
    >that you have this extension enabled. Disable it and VC will also issue
    >an error message.
    >
    >> class A
    >> {
    >> public:
    >> A() { }
    >> A(const A&) { }
    >> ~A() { }
    >> };
    >>
    >> A& operator<<(A& a, const char* p)
    >> {
    >> return a;
    >> }
    >>
    >> A f()
    >> {
    >> return A();
    >> }
    >>
    >> int main()
    >> {
    >> f() << "Hello";
    >> return 0;
    >> }

    >
    >You can make this compile by implementing 'operator<<' as a member
    >function of class 'A'. There's certain asymmetry in C++ behavior when it
    >comes to things like this...


    Doesn't the problem actually stem from the temporary A which is
    created from the temporary returned by f() in order to bind to the
    non-const reference argument declared by operator<<()?

    The standard says that object return values are always rvalues.

    If we rewrite f() thus:

    A& f()
    {
    static A a;
    return a;
    }

    then it should compile.

    Whether or not this is a good design is yet another issue.


    --
    Bob Hairgrove
    Bob Hairgrove, Jun 12, 2004
    #3
  4. Bob Hairgrove wrote:
    > On Fri, 11 Jun 2004 11:24:13 -0700, Andrey Tarasevich
    > <> wrote:
    >
    >>red floyd wrote:
    >>> ...
    >>> Am I allowed to pass the anonymous temporary returned by f() to a
    >>> function requiring a non-const reference?

    >>
    >>No.
    >>
    >>> I suspect G++ is correct, and VC is (again) braindead.

    >>
    >>VC supports this as an extension. The only reason it compiles on VC is
    >>that you have this extension enabled. Disable it and VC will also issue
    >>an error message.
    >>
    >>> class A
    >>> {
    >>> public:
    >>> A() { }
    >>> A(const A&) { }
    >>> ~A() { }
    >>> };
    >>>
    >>> A& operator<<(A& a, const char* p)
    >>> {
    >>> return a;
    >>> }
    >>>
    >>> A f()
    >>> {
    >>> return A();
    >>> }
    >>>
    >>> int main()
    >>> {
    >>> f() << "Hello";
    >>> return 0;
    >>> }

    >>
    >>You can make this compile by implementing 'operator<<' as a member
    >>function of class 'A'. There's certain asymmetry in C++ behavior when it
    >>comes to things like this...

    >
    > Doesn't the problem actually stem from the temporary A which is
    > created from the temporary returned by f() in order to bind to the
    > non-const reference argument declared by operator<<()?


    Yes. That's the immediate reason for the error message, as was already
    stated above. However, one way to work around the problem is, once
    again, to implement 'operator<<' as a member function of class 'A'.

    class A {
    public:
    ...
    A& operator<<(const char* p) { return *this; }
    };

    A f() {
    return A();
    }

    int main() {
    f() << "Hello"; // OK, no error
    return 0;
    }

    C++ permits non-constant member function calls on temporary objects. I
    can't say whether this is a viable solution in OP's case because all I
    have is the above piece of abstract code.

    --
    Best regards,
    Andrey Tarasevich
    Andrey Tarasevich, Jun 14, 2004
    #4
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. sam pal
    Replies:
    3
    Views:
    527
    E. Robert Tisdale
    Jul 16, 2003
  2. Ryan Mitchley
    Replies:
    2
    Views:
    368
    Ryan Mitchley
    Oct 16, 2003
  3. Greenhorn
    Replies:
    15
    Views:
    799
    Keith Thompson
    Mar 6, 2005
  4. Arv
    Replies:
    15
    Views:
    904
    James Kanze
    Mar 7, 2008
  5. Carl Forsman

    return type vs passing a reference

    Carl Forsman, Nov 15, 2008, in forum: C++
    Replies:
    13
    Views:
    476
    James Kanze
    Nov 17, 2008
Loading...

Share This Page