Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Workarounds for no 'rvalue references to *this' feature

I have a proxy container class around a movable object, and wish the proxy to be able to implicitly yield an rvalue reference to the underlying object, but only when the proxy itself is being moved.

I believe that I will be able to implement this behaviour as per proposal n2439 "Extending move semantics to *this", but it is not yet available in a release of gcc and won't be for a while.

The code below is what I am ultimately aiming for, but is not currently possible. Until this feature is available to me, are there any equivalent workarounds?

template< class T > struct movable_proxy {     operator T&&() && {         return std::move(value);     }      operator const T&() const& {         return value;     }  private:     T value; }; 
like image 688
boycy Avatar asked Jan 28 '13 13:01

boycy


People also ask

How do I create an rvalue reference?

An rvalue reference is formed by placing an && after some type. An rvalue reference behaves just like an lvalue reference except that it can bind to a temporary (an rvalue), whereas you can not bind a (non const) lvalue reference to an rvalue.

How do you use rvalue reference in C++?

If the function argument is an rvalue, the compiler deduces the argument to be an rvalue reference. For example, assume you pass an rvalue reference to an object of type X to a template function that takes type T&& as its parameter. Template argument deduction deduces T to be X , so the parameter has type X&& .

What is R value reference in C++11?

In C++11, however, the rvalue reference lets us bind a mutable reference to an rvalue, but not an lvalue. In other words, rvalue references are perfect for detecting whether a value is a temporary object or not.


1 Answers

Good question. I attempted writing a similar sort of proxy class recently but never achieved a good solution. The best I found was calling a member function on every use where the proxy was required to be an r-value:

ORef<T> move() {     return ORef<T>( this->release() ); } 

This changes the semantics of declaring something an r-value from std::move(proxy) to proxy.move(), but also allows the possibility of returning an object of a different type (implicitly convertible to your required type).

My coding practice using this was to always pass proxy objects as rvalues which forced manual specification of semantics (move, shared reference, copy or whatever), but that of course makes usage errors a potential problem (e.g. calling x.move() prior to the final usage of x).

like image 121
dhardy Avatar answered Sep 20 '22 17:09

dhardy