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?
Asked
Active
Viewed 189 times
11

Hen3
- 175
- 8
1 Answers
16
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.

cigien
- 57,834
- 11
- 73
- 112
-
3Why not `DenseMatrix&& Transpose() &&`? I.e. modifying an r-value in-place. – Maxim Egorushkin Jul 17 '20 at 17:05
-
1@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. – cigien Jul 17 '20 at 17:06
-
2@cigien `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 https://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"._ – Maxim Egorushkin Jul 17 '20 at 17:08
-
@MaximEgorushkin Aah, ok, that makes sense, thanks. It could still be optimized, but it's not guaranteed to. – cigien Jul 17 '20 at 17:08
-
Why there is `&&` after #2 `Transpose()`? I am unfamiliar with this syntax – Piotr Barejko Jul 17 '20 at 17:15
-
1It'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 :) – cigien Jul 17 '20 at 17:16
-
@cigien where is this documented? I am googling and I can't find it. – Piotr Barejko Jul 17 '20 at 17:20
-
2@bar3 https://en.cppreference.com/w/cpp/language/member_functions#ref-qualified_member_functions – Maxim Egorushkin Jul 17 '20 at 17:21
-
For a somewhat exhaustive general Q&A on ref-qualifiers, see [What does the & (ampersand) at the end of member function signature mean?](https://stackoverflow.com/questions/47002799/what-does-the-ampersand-at-the-end-of-member-function-signature-mean/47003980#47003980). – dfrib Jul 19 '20 at 21:57