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?
Is it possible to return the current object if it is an r-value reference?
Asked Answered
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.
@MaximEgorushkin I thought of that, but it feels like copy elision would take care of that. I'm not sure though. Edited anyway, since it can't hurt at least. –
Varioloid
@Varioloid
this
is a hidden function argument, and returning a function argument prevents return-value optimization and because this
is not an object with automatic storage duration here. See en.cppreference.com/w/cpp/language/copy_elision : In a return statement, when the operand is the name of a non-volatile object with automatic storage duration, which isn't a function parameter or a catch clause parameter, and which is of the same class type (ignoring cv-qualification) as the function return type. This variant of copy elision is known as NRVO, "named return value optimization". –
Scribbler @MaximEgorushkin Aah, ok, that makes sense, thanks. It could still be optimized, but it's not guaranteed to. –
Varioloid
Why there is
&&
after #2 Transpose()
? I am unfamiliar with this syntax –
Caras It's the syntax that constrains the function to be called on r-values. In fact this syntax was introduced in c++11 to achieve exactly the effect you're looking for :) –
Varioloid
@Varioloid where is this documented? I am googling and I can't find it. –
Caras
@bar3 en.cppreference.com/w/cpp/language/… –
Scribbler
For a somewhat exhaustive general Q&A on ref-qualifiers, see What does the & (ampersand) at the end of member function signature mean?. –
Bergstrom
© 2022 - 2024 — McMap. All rights reserved.
DenseMatrix&& Transpose() &&
? I.e. modifying an r-value in-place. – Scribbler