#include <iostream>
template <typename D>
struct MatrixBase {};
struct Matrix: MatrixBase<Matrix> {};
template <typename L, typename R>
struct AddOp: MatrixBase<AddOp<L, R>> {};
template <typename L, typename R>
AddOp<L, R> operator+(MatrixBase<L>, MatrixBase<R>) { return AddOp<L, R>(); }
#define PRINT_MY_NAME std::cout << __PRETTY_FUNCTION__ << '\n'
template<typename Derived>
void f(const MatrixBase<Derived>&) // (1)
{
PRINT_MY_NAME;
}
template<typename Derived>
void f(MatrixBase<Derived>&&) // (2)
{
PRINT_MY_NAME;
}
int main()
{
Matrix A;
f(A); // invokes (1)
f(A + A); // invokes also (1) !!!
}
I2luY2x1ZGUgPGlvc3RyZWFtPgoKdGVtcGxhdGUgPHR5cGVuYW1lIEQ+CnN0cnVjdCBNYXRyaXhCYXNlIHt9OwoKc3RydWN0IE1hdHJpeDogTWF0cml4QmFzZTxNYXRyaXg+IHt9OwoKdGVtcGxhdGUgPHR5cGVuYW1lIEwsIHR5cGVuYW1lIFI+CnN0cnVjdCBBZGRPcDogTWF0cml4QmFzZTxBZGRPcDxMLCBSPj4ge307Cgp0ZW1wbGF0ZSA8dHlwZW5hbWUgTCwgdHlwZW5hbWUgUj4KQWRkT3A8TCwgUj4gb3BlcmF0b3IrKE1hdHJpeEJhc2U8TD4sIE1hdHJpeEJhc2U8Uj4pIHsgcmV0dXJuIEFkZE9wPEwsIFI+KCk7IH0KCgojZGVmaW5lIFBSSU5UX01ZX05BTUUgc3RkOjpjb3V0IDw8IF9fUFJFVFRZX0ZVTkNUSU9OX18gPDwgJ1xuJwoKdGVtcGxhdGU8dHlwZW5hbWUgRGVyaXZlZD4Kdm9pZCBmKGNvbnN0IE1hdHJpeEJhc2U8RGVyaXZlZD4mKSAvLyAoMSkKewogICAgUFJJTlRfTVlfTkFNRTsKfQoKdGVtcGxhdGU8dHlwZW5hbWUgRGVyaXZlZD4Kdm9pZCBmKE1hdHJpeEJhc2U8RGVyaXZlZD4mJikgICAgICAvLyAoMikKewogICAgUFJJTlRfTVlfTkFNRTsKfQoKaW50IG1haW4oKQp7CiAgICBNYXRyaXggQTsKCiAgICBmKEEpOyAgICAgLy8gaW52b2tlcyAoMSkKICAgIGYoQSArIEEpOyAvLyBpbnZva2VzIGFsc28gKDEpICEhIQp9