Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it possible to return the current object if it is an r-value reference?

I have recently learned about r-value references. In order to more thoroughly experiment I decided to write a simple DenseMatrix class. My question is is it possible to write any function ( Transpose for this example ) such that for auto A = B.Transpose() separate matrix is returned, but for auto A = (B + C).Transpose() the result of the Transpose is calculated in place?

like image 350
Hen3 Avatar asked Jul 17 '20 16:07

Hen3


People also ask

Can a function return rvalue reference?

Typically rvalues are temporary objects that exist on the stack as the result of a function call or other operation. Returning a value from a function will turn that value into an rvalue. Once you call return on an object, the name of the object does not exist anymore (it goes out of scope), so it becomes an rvalue.

Can reference to an object be returned?

1 Answer. Easy explanation - This is possible but not always, since the reference being returned may get destroyed with the return of method. This is an undesirable condition, hence it is not always possible to return references. But it is always possible if the referred element is not local to the method.

What are r value references?

Rvalue references is a small technical extension to the C++ language. Rvalue references allow programmers to avoid logically unnecessary copying and to provide perfect forwarding functions. They are primarily meant to aid in the design of higer performance and more robust libraries.

What does it mean to return a reference to an object?

It means you return by reference, which is, at least in this case, probably not desired. It basically means the returned value is an alias to whatever you returned from the function. Unless it's a persistent object it's illegal.


1 Answers

Yes, you can overload the Transpose member function on the ref-qualification of the object it's being called on:

class DenseMatrix {
 
  DenseMatrix Transpose() const & {  // #1 called on l-values
     auto copy = *this;
     // transpose copy
     return copy;
  }

  DenseMatrix&& Transpose() && {  // #2 called on r-values
     // transpose *this
     return std::move(*this);
  }
};

So you get the result:

B.Transpose();        // calls #1
(B + C).Transpose();  // calls #2

Here's a demo.

Note that you could implement the l-value overload in terms of the r-value overload, like this:

DenseMatrix Transpose() const & {  
  auto copy = *this;
  return std::move(copy).Transpose();
}

Here's a demo.

like image 68
cigien Avatar answered Nov 15 '22 17:11

cigien