#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) !!!
}