Значение встроенных и пользовательских типов отличается в случае временных значений: временное значение int
в вашем примере является значением r, а временное значение S
является значением l.
Редактировать: Технически все временные значения являются r-значениями, но операторы работают с пользовательскими типами по-разному, потому что они на самом деле являются замаскированными обычными функциями. Это означает, что вы можете делать с ними некоторые вещи, не относящиеся к rvalue, такие как S()
в качестве левой части оператора присваивания по умолчанию!
Используйте declval
, чтобы получить lvalue или rvalue произвольного типа в не оцененном контексте:
#include <utility>
// declval<T&> yields an lvalue, declval<T> an rvalue
typedef decltype(std::declval<int&>()++) T1; // int
typedef decltype(++std::declval<int&>()) T2; // int&
typedef decltype(std::declval<S&>()++) T3; // S
typedef decltype(++std::declval<S&>()) T4; // S&