Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C++ > this by rvalue

Reply
Thread Tools

this by rvalue

 
 
Jan Bielawski
Guest
Posts: n/a
 
      06-01-2009
I was reading up on the new C++0x features and have a question:

Is there a way to overload on the rvalue-ness of the invoking object
itself? In other words, distinguish between:

// contrived example
X x;
x.foo();

and:

X f();
f().foo();

A less contrived example would be a member X:perator+() which would
distinguish between the first and the second invocation in the line
below:

X x, y, z;
X xx = x + y + z

So the first + sign would resolve to <lvalue>.operator+(y), and the
second + sign would resolve to <rvalue>.operator+(z)
(where the second one is presumably moving instead of copying).

Is this available? Is it at all useful? It's as if there was a "&&"
qualifier (or whatever it's called) analogous to "const" in method
declaration:

X X:perator+(const X& rhs) {...} // as usual
X X:perator+(const X& rhs) && {...} // the one invoked on
rvalue
X X:perator+(const X& rhs) const {...} // the one invoked on
const

Does this even make any sense?

--
Jan
 
Reply With Quote
 
 
 
 
SG
Guest
Posts: n/a
 
      06-02-2009
On 2 Jun., 01:16, Jan Bielawski <(E-Mail Removed)> wrote:
> I was reading up on the new C++0x features and have a question:
>
> Is there a way to overload on the rvalue-ness of the invoking object
> itself? In other words, distinguish between:
>
> * * // contrived example
> * * X x;
> * * x.foo();
>
> and:
>
> * * X f();
> * * f().foo();


Yes. That's where "ref qualifiers" come in:

class X {
public:
void foo() &;
void foo() &&;
};

> A less contrived example would be a member X:perator+() which would
> distinguish between the first and the second invocation in the line
> below:
>
> * * X x, y, z;
> * * X xx = x + y + z
>
> So the first + sign would resolve to <lvalue>.operator+(y), and the
> second + sign would resolve to <rvalue>.operator+(z)
> (where the second one is presumably moving instead of copying).


Possible but unusable. I would write a free operator+ in terms of +=:

class X {
public:
...
X& operator=(X const&) &;
X& operator=(X &&) &;

X& operator+=(X const&) &;
X& operator+=(X &&) &;
...
};

inline X operator+(X const& lhs, X const& rhs) {
X temp = lhs;
temp += rhs;
return temp;
}

inline X operator+(X && lhs, X const& rhs) {
return std::move(lhs += rhs);
}

> Is this available? Is it at all useful? It's as if there was a "&&"
> qualifier (or whatever it's called) analogous to "const" in method
> declaration:
>
> * * X X:perator+(const X& rhs) {...} *// as usual
> * * X X:perator+(const X& rhs) && {...} *// invoked on rvalue
> * * X X:perator+(const X& rhs) const {...} *// invoked on const


Almost. You can't overload the functions like this. You can't have two
member function which only differ in one lacking a ref qualifier and
the other one having some ref qualifier. To make this work you need to
add an lvalue ref qualifier ("&") for the first function. But what
would be the difference between the first and the third function? I
hope none. You should at least remove the first function.

Cheers!
SG
 
Reply With Quote
 
 
 
 
Niels Dekker - no reply address
Guest
Posts: n/a
 
      06-02-2009
Jan Bielawski wrote:
>> Is there a way to overload on the rvalue-ness of the invoking object
>> itself?


SG wrote:
> Yes. That's where "ref qualifiers" come in:
>
> class X {
> public:
> void foo() &;
> void foo() &&;
> };


>> Is this available?


Good question. Is there any compiler already supporting ref qualifiers for
member functions?

>> Is it at all useful?


I do think so, yes. Have a look at the examples from a paper by Daveed
Vandevoorde and Bronek Kozicki, Extending Move Semantics To *this,
http://www.open-std.org/jtc1/sc22/wg...2005/n1821.htm

The first example shows how an lvalue ref qualifier can be used to avoid
accidentally taking the address of an rvalue, or assigning to an rvalue:

struct S {
S* operator &() &;
S& operator=(S const&) &;
};

The second example shows how an rvalue ref qualifier allows move semantics
for the data of an rvalue object:

class X {
std::vector<char> data_;
public:
// ...
std::vector<char> const & data() const & { return data_; }
std::vector<char> && data() && { return data_; }
};

(Both examples are from the paper.)

Actually I did a proposal to add lvalue ref qualifiers to assignment
operators in the Standard Library. Written together with Daniel Kruegler:
http://www.open-std.org/jtc1/sc22/wg...009/n2819.html
Hopefully, it will be discussed during the next meeting of the std
committee...


Kind regards, Niels
--
Niels Dekker
http://www.xs4all.nl/~nd/dekkerware
Scientific programmer at LKEB, Leiden University Medical Center




 
Reply With Quote
 
SG
Guest
Posts: n/a
 
      06-02-2009
On 2 Jun., 09:42, "Niels Dekker - no reply address"
<(E-Mail Removed)> wrote:
>
> The second example shows how an rvalue ref qualifier allows move semantics
> for the data of an rvalue object:
>
> * class X {
> * *std::vector<char> data_;
> * public:
> * *// ...
> * *std::vector<char> const & data() const & { return data_; }
> * *std::vector<char> && data() && { return data_; }
> * };


Interesting. But this is not in line anymore with the current state of
rvalues references. It won't compile without an explicit move:

std::vector<char> && data() && { return std::move(data_); }

You may even want to return the vector by value to avoid a dangling
reference in this case:

X foo();
std::vector<char> const& bar = foo().data();

Then again, defining references to const in this way could be a thing
of the past. I hope people will rely more on copy elision and move
semantics in these cases.

Cheers!
SG
 
Reply With Quote
 
Niels Dekker - no reply address
Guest
Posts: n/a
 
      06-02-2009
>> class X {
>> std::vector<char> data_;
>> public:
>> // ...
>> std::vector<char> const & data() const & { return data_; }
>> std::vector<char> && data() && { return data_; }
>> };



SG wrote:
> Interesting. But this is not in line anymore with the current state of
> rvalues references. It won't compile without an explicit move:
>
> std::vector<char> && data() && { return std::move(data_); }


Oops! Sorry for spreading outdated information :-0 The paper is from
2005.


> You may even want to return the vector by value to avoid a dangling
> reference in this case:
>
> X foo();
> std::vector<char> const& bar = foo().data();
>
> Then again, defining references to const in this way could be a thing
> of the past. I hope people will rely more on copy elision and move
> semantics in these cases.


LOL I'll try to ammend my programming style...

But in general you may not want to require that your data is
CopyConstructible (or even MoveConstructible). So you may still want to
have the rvalue-ref-qualified overload of the data() function return an
rvalue reference. Don't you think?


Kind regards, Niels

 
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
Giving an rvalue ref to a function taking an rvalue ref Juha Nieminen C++ 13 08-29-2012 09:25 PM
operators requiring lvalue/rvalue operands and resulting in rvalue/lvalue Kavya C Programming 9 10-28-2006 01:45 AM
lvalue rvalue Denis Remezov C++ 12 10-18-2004 09:11 AM
rvalue / lvalue operator[] Gonzalo Aguirre C++ 4 01-02-2004 06:02 PM
++x returns lvalue but x++ return rvalue Chris Mantoulidis C++ 4 12-29-2003 07:00 AM



Advertisments