Вот немного измененная версия вашего кода:
#include <iostream>
#if 0
using T = int;
#else
struct T {T(int){}};
#endif
using namespace std;
class A {
public:
A (T const &&i) { cout << "const rvalue constructor"; }
A (T &&i) { cout << "non const rvalue constructor"; }
};
T const
foo (void)
{
const T i = 3;
return i;
}
int main()
{
A a(foo());
}
Когда T == int
, вы получаете неконстантную перегрузку. Когда T
является типом класса, вы получаете перегрузку const. Это поведение выпадает из раздела 8.2.2 [expr.type] / p2:
Если изначально значение prvalue имеет тип « cv T
», где T
- неквалифицированный cv некласс, тип не массив, тип выражения корректируется на T
до дальнейшего анализа.
Перевод: язык не имеет const
-качественных скалярных значений. Их просто не существует.