"lifetime of temporary bound to reference..."

Discussion in 'C++' started by Igor R., Jan 26, 2009.

  1. Igor R.

    Igor R. Guest

    Hello,

    Does the rule in the subj applies to the following:

    std::pair<int, int> getPair()
    {
    return std::pair<int, int>(1, 2);
    }

    int main()
    {
    // is this legal?
    const std::pair<int, int> &p1 = getPair();
    // and this?
    std::pair<int, int> &p2 = getPair();
    std::cout << p1.first << p2.second;
    }
     
    Igor R., Jan 26, 2009
    #1
    1. Advertising

  2. Igor R.

    James Kanze Guest

    On Jan 26, 7:25 pm, Victor Bazarov <> wrote:
    > Igor R. wrote:
    > > Does the rule in the subj applies to the following:


    First, very importantly, the rule in the subject doesn't exist.
    Whether a temporary is bound to a reference has no effect on its
    lifetime. The only time the lifetime of a temporary is extended
    is if a reference is initialized with a rvalue. (The
    difference, of course, is whether a temporary is bound to a
    reference is a transitive relationship; whether a temporary was
    initialized with an rvalue isn't.)

    > > std::pair<int, int> getPair()
    > > {
    > > return std::pair<int, int>(1, 2);
    > > }


    > > int main()
    > > {
    > > // is this legal?
    > > const std::pair<int, int> &p1 = getPair();


    > Yes, this is legal. The temporary returned by 'getPair' will
    > have the same lifetime as the 'p1' reference (i.e. until
    > 'main' returns).


    Formally, it might be a copy of the temporary (which is also a
    temporary) which has its lifetime extended (but I think this
    possibility will be removed from C++0x).

    > > // and this?
    > > std::pair<int, int> &p2 = getPair();


    > No, this is not legal. A temporary can only be bound to a
    > reference to const.


    No! A reference can only be initialized with an rvalue if it is
    const and non volatile. But it's quite possible to arrange for
    a temporary to bind to a non-const reference (const_cast, member
    functions, etc.).

    This point is in some ways related to my initial comment, above:
    in order to bind a temporary to a non-const reference, you must
    somehow arrange for the expression to be an lvalue. And since
    the initialization expression of the temporary is not an rvalue,
    the lifetime of the temporary will NOT be extended.

    This is probably best explained with a simple example:

    struct S
    {
    S& me() { return *this ; }
    } ;

    S& rs = S().me() ;

    The reference rs is clearly bound to a temporary, even though
    the reference is non-const. On the other hand, the reference
    was not initialized with an rvalue expression, so the lifetime
    of the temporary will NOT be extended beyond the end of the full
    expression. (Technically, the temporary object S() will be
    destructed before the reference rs is initialized. In practice,
    there's no way a conforming program can tell, however.)

    --
    James Kanze (GABI Software) email:
    Conseils en informatique orientée objet/
    Beratung in objektorientierter Datenverarbeitung
    9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
     
    James Kanze, Jan 27, 2009
    #2
    1. Advertising

  3. Igor R.

    James Kanze Guest

    On Jan 27, 2:49 pm, Victor Bazarov <> wrote:
    > James Kanze wrote:
    > > On Jan 26, 7:25 pm, Victor Bazarov <> wrote:
    > >> Igor R. wrote:
    > >>> Does the rule in the subj applies to the following:


    > > First, very importantly, the rule in the subject doesn't
    > > exist. Whether a temporary is bound to a reference has no
    > > effect on its lifetime. The only time the lifetime of a
    > > temporary is extended is if a reference is initialized with
    > > a rvalue. (The difference, of course, is whether a
    > > temporary is bound to a reference is a transitive
    > > relationship; whether a temporary was initialized with an
    > > rvalue isn't.)


    > I believe you're attempting to split hairs. Please see the
    > second sentence of 12.2/5. "The temporary to which the
    > reference is bound ... persists for the lifetime of the
    > reference". If that's not "lifetime of temporary bound to
    > reference", what exactly is it?


    That's an interesting quote, because of course, it's neither
    implementable, nor implemented.

    My point wasn't meant to split hairs. It was to point out a
    very important distinction: the fact that the extension of
    lifetime is not transitive. The lifetime is only extended to
    match that of the reference which was initialized with the
    expression generating the temporary. The fact that some
    reference is bound to a temporary doesn't guarantee that that
    temporary will not be destroyed while the reference is still
    usable.

    --
    James Kanze (GABI Software) email:
    Conseils en informatique orientée objet/
    Beratung in objektorientierter Datenverarbeitung
    9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
     
    James Kanze, Jan 28, 2009
    #3
    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.

Share This Page