Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C++ > More C++0x - custom move()

Reply
Thread Tools

More C++0x - custom move()

 
 
Noah Roberts
Guest
Posts: n/a
 
      04-07-2010
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...ferences-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/WG...2812.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/
 
Reply With Quote
 
 
 
 
Bo Persson
Guest
Posts: n/a
 
      04-07-2010
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...ferences-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/WG...2812.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...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


 
Reply With Quote
 
 
 
 
Noah Roberts
Guest
Posts: n/a
 
      04-07-2010
In article <(E-Mail Removed)>, http://www.velocityreviews.com/forums/(E-Mail Removed) 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...ferences-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/WG...2812.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...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/
 
Reply With Quote
 
Paul Bibbings
Guest
Posts: n/a
 
      04-07-2010
Noah Roberts <(E-Mail Removed)> 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
 
Reply With Quote
 
Howard Hinnant
Guest
Posts: n/a
 
      04-08-2010
On Apr 7, 5:53*pm, Paul Bibbings <(E-Mail Removed)> wrote:
> Noah Roberts <(E-Mail Removed)> 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
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Kamaelia 0.4.0 RELEASED - Faster! More Tools! More Examples! More Docs! ;-) Michael Python 4 06-26-2006 08:00 AM
With a Ruby Yell: more, more more! Robert Klemme Ruby 5 09-29-2005 06:37 AM
Databinding to custom properties of a custom class in ASP.NET 2 =?Utf-8?B?SW1hciBTcGFhbmphYXJz?= ASP .Net 0 04-20-2005 07:34 PM
Capturing event from other custom control within another custom control Jonah Olsson ASP .Net 1 04-05-2005 01:39 PM
Question: Invoking custom file type (file associated with custom app) VB Programmer ASP .Net 1 11-03-2003 11:49 PM



Advertisments