Выражение не только имеет значение и тип, но также имеет значение категория .Эта категория может быть
- Значение l: Эти выражения обычно ссылаются на объявленные объекты, ссылки, функции или результаты разыменования указателей.
- Значение x: это результат создания безымянной ссылки на rvalue.R-значения ссылок создаются
T&&
вместо T&
.Это концепция C ++ 11, и вы можете проигнорировать их здесь.Упоминается только для полноты. - Значение: Это результаты приведения к не ссылочным типам (например,
A(10)
) или вычисления / указания значения, например, 42
или 2 + 3
.
Ссылка lvalue требует выражения lvalue для инициализации.То есть следующее недопустимо:
A &x = A(10);
Причина этого заключается в том, что только выражения lvalue относятся к вещам, которые подходят и предназначены для того, чтобы оставаться в живых дольше, чем только на время инициализации.Например, объявленный объект действует до выхода из своего блока (если это была локальная нестатическая переменная) или до конца программы (если он был объявлен вне функций и классов).Выражение rvalue A(10)
относится к объекту, который умирает уже после завершения инициализации.И если бы вы сказали следующее, это не имело бы никакого смысла, потому что чистые значения, такие как 10
, вообще не имеют адреса, но ссылки требуют некоторой идентичности, с которой они связываются, что на практике реализуетсявзятие адреса их цели внутри компиляторов
int &x = 10; // makes totally no sense
Но для константных ссылок C ++ имеет бэкдор.При инициализации с помощью prvalue ссылка на const lvalue автоматически продлевает время жизни объекта, если выражение ссылается на объект.Если выражение имеет необъектное значение, C ++ создает временный объект со значением этого выражения и удлиняет время жизни этого временного объекта, привязывая ссылку к этому временному объекту:
// lifetime of the temporary object is lengthened
A const& x = A(10);
// lifetime of the automatically created temporary object is lengthened
int const& x = 10;
Чтопроисходит в вашем случае?
Теперь компилятор в вашем случае, поскольку вы предоставляете временный объект, будет выбирать версию с типом параметра A const&
, а не с параметром A&
.