A reference to non-const to be bound to a temporary object

Discussion in 'C++' started by John Ky, Feb 20, 2004.

  1. John Ky

    John Ky Guest

    Hello:

    I'm not sure how to word this question properly, so I'll start by
    listing the code I am having problems with:

    int main()
    {
    std::vector<int> x;
    x.swap(std::vector<int>());
    return 0;
    }

    This is also not allowed:

    std::vector<int> get()
    {
    return std::vector<int>();
    }

    int main()
    {
    std::vector<int> x;
    x.swap(get());
    return 0;
    }


    I was told on another newsgroup that the following code is
    nonstandard C++. The reason being that "Standard C++
    doesn't allow a reference to non-const to be bound to a
    temporary object."

    But being able to bind a reference to non-const to a temporary
    object is useful for taking advantage of using a swap method.

    I find it useful to be able to avoid this restriction because
    it allows me to wrap resources that are expensive to create
    and destroy into a class and then move it around while
    minimising copying and guaranteeing exception safety by
    using a swap function, all in a concise piece of code.

    For instance if the Resource class wrapped an expensive
    resource and the create static method creates the resource
    while the open static method opens the resource:

    // Resource interface:
    Resource Resource::eek:pen(char *name);
    Resource Resource::create(char *name);

    // Some code:
    Resource resource1;
    Resource resource2;

    resource1.swap(Resource::eek:pen("XYZ"));
    resource2.swap(Resource::create("abc"));

    I'm therefore interested in the motivation for this restriction and
    if there is another way to do the same job just as efficiently.

    -John
     
    John Ky, Feb 20, 2004
    #1
    1. Advertising

  2. John Ky wrote in news::

    > Hello:
    >
    > I'm not sure how to word this question properly, so I'll start by
    > listing the code I am having problems with:
    >
    > int main()
    > {
    > std::vector<int> x;
    > x.swap(std::vector<int>());


    change to:

    std::vector<ont>().swap( x );

    > return 0;
    > }
    >


    HTH.

    Rob.
    --
    http://www.victim-prime.dsl.pipex.com/
     
    Rob Williscroft, Feb 20, 2004
    #2
    1. Advertising

  3. John Ky wrote:
    > ...
    > I'm therefore interested in the motivation for this restriction and
    > if there is another way to do the same job just as efficiently.
    > ...


    Just do it other way around

    std::vector<int> x;
    std::vector<int>().swap(x);

    or in your case

    Resource resource1;
    Resource resource2;

    Resource::eek:pen("XYZ").swap(resource1);
    Resource::create("abc").swap(resource2);

    --
    Best regards,
    Andrey Tarasevich
     
    Andrey Tarasevich, Feb 20, 2004
    #3
  4. John Ky

    Jeff Schwab Guest

    John Ky wrote:

    <snip> intro </>

    > int main()
    > {
    > std::vector<int> x;
    > x.swap(std::vector<int>());
    > return 0;
    > }


    <snip> more example code </>

    > I was told on another newsgroup that the following code is
    > nonstandard C++. The reason being that "Standard C++
    > doesn't allow a reference to non-const to be bound to a
    > temporary object."
    >
    > But being able to bind a reference to non-const to a temporary
    > object is useful for taking advantage of using a swap method.


    <snip/>

    > I'm therefore interested in the motivation for this restriction and
    > if there is another way to do the same job just as efficiently.


    In this particular case, x.clear( ) is probably the most efficient and
    concise option.
     
    Jeff Schwab, Feb 20, 2004
    #4
  5. "John Ky" <> wrote in message
    news:...
    >
    > int main()
    > {
    > std::vector<int> x;
    > x.swap(std::vector<int>());
    > return 0;
    > }


    Do it this way:

    std::vector<int>().swap(x);
     
    Andrew Koenig, Feb 20, 2004
    #5
  6. John Ky

    David Harmon Guest

    On Fri, 20 Feb 2004 15:57:51 GMT in comp.lang.c++, "Andrew Koenig"
    <> was alleged to have written:

    >> x.swap(std::vector<int>());



    >Do it this way:
    >
    > std::vector<int>().swap(x);


    The fact that one of those would work and the other not just points out
    the sillyness of the rule against binding non-const references to
    temporaries.
     
    David Harmon, Feb 20, 2004
    #6
  7. John Ky

    tom_usenet Guest

    On Fri, 20 Feb 2004 16:59:02 GMT, David Harmon <>
    wrote:

    >On Fri, 20 Feb 2004 15:57:51 GMT in comp.lang.c++, "Andrew Koenig"
    ><> was alleged to have written:
    >
    >>> x.swap(std::vector<int>());

    >
    >
    >>Do it this way:
    >>
    >> std::vector<int>().swap(x);

    >
    >The fact that one of those would work and the other not just points out
    >the sillyness of the rule against binding non-const references to
    >temporaries.


    The rule isn't silly except in the exact type match case (of which
    vector::swap is an example).

    Tom

    C++ FAQ: http://www.parashift.com/c -faq-lite/
    C FAQ: http://www.eskimo.com/~scs/C-faq/top.html
     
    tom_usenet, Feb 20, 2004
    #7
  8. In article <>,
    tom_usenet <> wrote:

    > On Fri, 20 Feb 2004 16:59:02 GMT, David Harmon <>
    > wrote:
    >
    > >On Fri, 20 Feb 2004 15:57:51 GMT in comp.lang.c++, "Andrew Koenig"
    > ><> was alleged to have written:
    > >
    > >>> x.swap(std::vector<int>());

    > >
    > >
    > >>Do it this way:
    > >>
    > >> std::vector<int>().swap(x);

    > >
    > >The fact that one of those would work and the other not just points out
    > >the sillyness of the rule against binding non-const references to
    > >temporaries.

    >
    > The rule isn't silly except in the exact type match case (of which
    > vector::swap is an example).


    I would argue that there are cases when even an exact type match case
    should not bind a temporary to a non-const reference:

    std::deque<int> stuff...
    std::advance(stuff.begin(), stuff.size()/2);

    I sure am glad this call to advance doesn't compile.

    That being said, there are times when you *do* want to bind a temporary
    to a non-const reference (and swap is certainly one of those times).
    The best person to decide when to bind a temp to a ref is the author of
    the function in question. And it would even be useful to overload two
    functions based on whether or not they were binding to an rvalue or
    lvalue:

    void foo(const A& a); // bind to lvalues
    void foo(A&& a); // bind to rvalues (proposed)

    This is exactly what the move proposal is about:

    http://anubis.dkuug.dk/jtc1/sc22/wg21/docs/papers/2002/n1377.htm

    I would love to see:

    template <class T, class A>
    void
    vector<T, A>::swap(vector&& v);

    which would then allow:

    x.swap(std::vector<int>());

    I also wouldn't mind seeing:

    template <class T> void swap(T&, T&);
    template <class T> void swap(T&&, T&);
    template <class T> void swap(T&, T&&);

    I.e. at most one of the arguments to swap can be a temporary.

    But I recommend keeping std::advance just the way it is (at least with
    respect to this issue) :)

    template <class InputIterator, class Distance>
    void
    advance(InputIterator& i, Distance n);

    -Howard
     
    Howard Hinnant, Feb 20, 2004
    #8
  9. John Ky

    John Ky Guest

    Re: A reference to non-const to be bound to a temporary object RESOLVED

    Ofcourse! Thankyou everyone for your help.

    Much appreciated.

    -John
     
    John Ky, Feb 23, 2004
    #9
  10. John Ky

    John Ky Guest

    > The rule isn't silly except in the exact type match case (of which
    > vector::swap is an example).


    The rule may not be silly, but error messages tend to be. Take gcc for
    example:

    ELPolicyInfo.cpp: In member function `ELPolicyInfo&
    ELPolicyInfo::eek:perator=(const ELPolicyInfo&)':
    ELPolicyInfo.cpp:136: no matching function for call to `ELPolicyInfo::swap(
    const ELPolicyInfo&)'
    ELPolicyInfo.cpp:125: candidates are: void ELPolicyInfo::swap(ELPolicyInfo&)

    Granted that this is a compiler issue rather than a language issue, but it
    would
    be nice if there were also a user-friendliness standard for C++ compilers
    that
    compiler implementations could strive for.

    -John
     
    John Ky, Feb 23, 2004
    #10
    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. =?ISO-8859-1?Q?Ney_Andr=E9_de_Mello_Zunion?=

    The temporary vs non-const reference love story

    =?ISO-8859-1?Q?Ney_Andr=E9_de_Mello_Zunion?=, Nov 4, 2003, in forum: C++
    Replies:
    13
    Views:
    591
    Ron Natalie
    Nov 6, 2003
  2. qazmlp
    Replies:
    4
    Views:
    1,399
    Buster
    May 6, 2004
  3. George2
    Replies:
    10
    Views:
    606
    Pete Becker
    Dec 17, 2007
  4. reppisch
    Replies:
    6
    Views:
    409
    Andrey Tarasevich
    May 6, 2008
  5. Replies:
    10
    Views:
    1,362
    James Kanze
    Nov 27, 2008
Loading...

Share This Page