More C++0x - custom move()

Discussion in 'C++' started by Noah Roberts, Apr 7, 2010.

  1. Noah Roberts

    Noah Roberts Guest

    I'm trying to understand the degredation principles behind references
    and rvalue vs. lvalue, etc... As such I decided to implement my own
    std::move() following this implementation:

    http://blogs.msdn.com/vcblog/archive/2009/02/03/rvalue-references-c-0x-
    features-in-vc10-part-2.aspx

    Doesn't work. Apparently VC2010 RC implements the changes specified in
    N2812:
    http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2008/n2812.html#the-
    problem

    The issue I'm having here is that upon playing with this definition I
    find that using the cast alone seems to work and I haven't been able to
    find a way to break it:

    template < typename T >
    T&& my_move(T&& t)
    {
    return static_cast<T&&>(t);
    }

    My question then is why is it implemented in the standard in a more
    complex manner using remove_reference<T>? I assume there's a very good
    and important reason, so how do I break my_move?

    --
    http://crazyeddiecpp.blogspot.com/
     
    Noah Roberts, Apr 7, 2010
    #1
    1. Advertising

  2. Noah Roberts

    Bo Persson Guest

    Noah Roberts wrote:
    > I'm trying to understand the degredation principles behind
    > references and rvalue vs. lvalue, etc... As such I decided to
    > implement my own std::move() following this implementation:
    >
    > http://blogs.msdn.com/vcblog/archive/2009/02/03/rvalue-references-c-0x-
    > features-in-vc10-part-2.aspx
    >
    > Doesn't work. Apparently VC2010 RC implements the changes
    > specified in N2812:
    > http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2008/n2812.html#the-
    > problem


    Yes, the blog entry (and VC2010 Beta) is using "rvalues v1". The
    Standard (and RC) is "rvalues v2".

    http://blogs.msdn.com/vcblog/archive/2010/04/06/c-0x-core-language-features-in-vc10-the-table.aspx

    >
    > The issue I'm having here is that upon playing with this definition
    > I find that using the cast alone seems to work and I haven't been
    > able to find a way to break it:
    >
    > template < typename T >
    > T&& my_move(T&& t)
    > {
    > return static_cast<T&&>(t);
    > }
    >
    > My question then is why is it implemented in the standard in a more
    > complex manner using remove_reference<T>? I assume there's a very
    > good and important reason, so how do I break my_move?


    I think it makes a difference, if you are moving from a reference
    (where T is U&).


    Bo Persson
     
    Bo Persson, Apr 7, 2010
    #2
    1. Advertising

  3. Noah Roberts

    Noah Roberts Guest

    In article <>, says...
    >
    > Noah Roberts wrote:
    > > I'm trying to understand the degredation principles behind
    > > references and rvalue vs. lvalue, etc... As such I decided to
    > > implement my own std::move() following this implementation:
    > >
    > > http://blogs.msdn.com/vcblog/archive/2009/02/03/rvalue-references-c-0x-
    > > features-in-vc10-part-2.aspx
    > >
    > > Doesn't work. Apparently VC2010 RC implements the changes
    > > specified in N2812:
    > > http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2008/n2812.html#the-
    > > problem

    >
    > Yes, the blog entry (and VC2010 Beta) is using "rvalues v1". The
    > Standard (and RC) is "rvalues v2".
    >
    > http://blogs.msdn.com/vcblog/archive/2010/04/06/c-0x-core-language-features-in-vc10-the-table.aspx


    Thanks. I wasn't able to find that list, only for the beta and lower.
    Looks like it has a couple additions as well.
    >
    > >
    > > The issue I'm having here is that upon playing with this definition
    > > I find that using the cast alone seems to work and I haven't been
    > > able to find a way to break it:
    > >
    > > template < typename T >
    > > T&& my_move(T&& t)
    > > {
    > > return static_cast<T&&>(t);
    > > }
    > >
    > > My question then is why is it implemented in the standard in a more
    > > complex manner using remove_reference<T>? I assume there's a very
    > > good and important reason, so how do I break my_move?

    >
    > I think it makes a difference, if you are moving from a reference
    > (where T is U&).
    >


    Yeah, I was confusing myself with some of my test code. I created a
    function f(T&&) and tried to call it with the result of my_move on an
    lvalue and it failed while std::move succeeds.

    --
    http://crazyeddiecpp.blogspot.com/
     
    Noah Roberts, Apr 7, 2010
    #3
  4. Noah Roberts <> writes:
    <snip />
    >
    > The issue I'm having here is that upon playing with this definition I
    > find that using the cast alone seems to work and I haven't been able to
    > find a way to break it:
    >
    > template < typename T >
    > T&& my_move(T&& t)
    > {
    > return static_cast<T&&>(t);
    > }
    >
    > My question then is why is it implemented in the standard in a more
    > complex manner using remove_reference<T>? I assume there's a very good
    > and important reason, so how do I break my_move?


    IIRC, the purpose of std::move is to convert to an rvalue. Your
    implementation here doesn't achieve that. Called with:

    struct X { /* ... */ };
    X x;
    my_move(x);

    x is an lvalue, and so T resolves to X& and, through reference
    collapsing, my_move becomes:

    T& my_move(T& t)
    {
    return static_cast<T&>(t);
    }

    and you have forwarding, not moving.

    As I see it, the very purpose of using remove_reference<T>::type in the
    implemenations that I have seen is to prevent just this reference
    collapsing in the return type.

    Regards

    Paul Bibbings
     
    Paul Bibbings, Apr 7, 2010
    #4
  5. On Apr 7, 5:53 pm, Paul Bibbings <> wrote:
    > Noah Roberts <> writes:
    >
    > <snip />
    >
    >
    >
    > > The issue I'm having here is that upon playing with this definition I
    > > find that using the cast alone seems to work and I haven't been able to
    > > find a way to break it:

    >
    > > template < typename T >
    > > T&& my_move(T&& t)
    > > {
    > >   return static_cast<T&&>(t);
    > > }

    >
    > > My question then is why is it implemented in the standard in a more
    > > complex manner using remove_reference<T>?  I assume there's a very good
    > > and important reason, so how do I break my_move?

    >
    > IIRC, the purpose of std::move is to convert to an rvalue.  Your
    > implementation here doesn't achieve that.  Called with:
    >
    >    struct X { /* ... */ };
    >    X x;
    >    my_move(x);
    >
    > x is an lvalue, and so T resolves to X& and, through reference
    > collapsing, my_move becomes:
    >
    >   T& my_move(T& t)
    >   {
    >     return static_cast<T&>(t);
    >   }
    >
    > and you have forwarding, not moving.
    >
    > As I see it, the very purpose of using remove_reference<T>::type in the
    > implemenations that I have seen is to prevent just this reference
    > collapsing in the return type.


    Paul is exactly correct.

    I just wanted to add one more bit: Although there's nothing wrong
    with writing my_move, especially for educational purposes, please
    don't write move() and expect it to be called by other code (such as
    the std::lib). move() is not a "customization point" like swap() is.
    std::move() should do the right thing for every single type (even
    yours) and so there is no motivation to customize it. I'm on a
    crusade to make sure that when anyone wants to move something they
    call std::move(x), not move(x). This frees up "move" to mean anything
    you want in your namespace, without fear that it will be accidentally
    called via ADL.

    -Howard
     
    Howard Hinnant, Apr 8, 2010
    #5
    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. Michael
    Replies:
    4
    Views:
    419
    Matt Hammond
    Jun 26, 2006
  2. Eduardo78
    Replies:
    0
    Views:
    258
    Eduardo78
    Nov 3, 2005
  3. Andrew Tomazos
    Replies:
    2
    Views:
    629
    Nobody
    Dec 12, 2011
  4. Robert Klemme

    With a Ruby Yell: more, more more!

    Robert Klemme, Sep 28, 2005, in forum: Ruby
    Replies:
    5
    Views:
    218
    Jeff Wood
    Sep 29, 2005
  5. Mrmaster Mrmaster

    Which is more expensive Rename or Move?

    Mrmaster Mrmaster, Jun 16, 2009, in forum: Ruby
    Replies:
    8
    Views:
    156
    Matthew K. Williams
    Jun 17, 2009
Loading...

Share This Page