номер
Спецификация языка C ++ никогда не дает такого простого утверждения, как то, о котором вы спрашиваете. В стандарте языка нигде не сказано, что «все временные объекты являются значениями». Более того, сам вопрос немного ошибочен, поскольку свойство быть значением в языке C ++ является не свойством объекта, а скорее свойством выражения (то есть свойством его результата). Это на самом деле так, как это определено в спецификации языка: для различных видов выражений говорится, когда результатом является lvalue, а когда это rvalue. Помимо прочего, это фактически означает, что временный объект может быть доступен как в виде значения, так и значения в зависимости от конкретной формы выражения, используемой для доступа.
Например, результатом литерального выражения 2 + 3
, очевидно, является значение rvalue, временное значение типа int
. Мы не можем применить к нему унарный &
, так как унарный &
требует lvalue в качестве операнда
&(2 + 3); // ERROR, lvalue required
Однако, как мы все знаем, постоянная ссылка может быть присоединена к временному объекту, как в
const int &ri = 2 + 3;
В этом случае ссылка прикрепляется к временному, продлевая срок службы последнего. Очевидно, что как только это будет сделано, мы получим доступ к тому же временному значению, что и lvalue ri
, поскольку ссылки всегда являются lvalue. Например, мы можем легко и легально применить унарный &
к ссылке и получить указатель на временный
const int *pi = &ri;
с указателем, который остается полностью действительным, пока сохраняется временное значение.
Другой очевидный пример доступа lvalue к временному объекту - это когда мы обращаемся к временному объекту типа класса через его указатель this
. Результатом *this
является lvalue (как всегда в случае с унарным *
, примененным к указателю данных), но это не меняет того факта, что фактический объект может легко быть временным. Для данного типа класса T
выражение T()
является r-значением, как это явно указано в стандарте языка, однако временный объект, доступ к которому осуществляется через выражение *T().get_this()
(с очевидной реализацией T::get_this()
), является lvalue. В отличие от предыдущего примера, этот метод позволяет сразу получить неконстантное lvalue, которое ссылается на временный объект.
Итак, еще раз, тот же самый временный объект может легко «рассматриваться» как r-значение или как l-значение в зависимости от того, какое выражение (какой путь доступа ) вы используете, чтобы «посмотреть» «на этом объекте.