Что такое "значение, не связанное с объектом"?
Стандарт С++ 11 и С++ 14 (и рабочий проект, соответственно), например, в §3.10.1:
Значение prvalue ( "чистое" значение r) является значением r, которое не является значением x. [Пример: результат вызова функции чей тип возврата не является ссылкой, является prvalue. Значение литерала, такого как 12, 7.3e5 или true, равно также prvalue. -end пример]
и
Значение r (так называемое, исторически, поскольку rvalues могут появляться в правой части задания выражение) представляет собой значение x, временный объект (12.2) или его подобъект или значение, которое не связано с объектом.
Что приводит меня к вопросу: как выражение может быть "значением, не связанным с объектом"?
У меня создалось впечатление, что целью выражения является возврат объектов или void
(что я тоже не ожидаю, что это значение).
Есть ли простой и общий пример для таких выражений?
Изменить 1
Чтобы еще больше усложнить ситуацию, рассмотрите следующее:
int const& x = 3;
int&& y = 4;
В контексте §8.3.2.5, в котором содержится наиболее интересный фрагмент:
[...] Ссылка должна быть инициализирована для ссылки на действительный объект или функция [...]
Это подкрепляется §8.5.3.1:
Переменная, объявленная как T & или T & &, то есть "ссылка на тип T" (8.3.2), должна быть инициализирована объектом, или функции типа T или объектом, который может быть преобразован в T. [...]
Ответы
Ответ 1
Примерами таких значений являются все non-array, неклассические временные prvalues (временная prvalue соответствует временному объекту). Примеры включают 2.0
и 1
. Контрпримеры включают "hello"
(который является массивом), std::string("haha")
(который является объектом класса) или float
prvalue, временно инициализированный из 2
, который привязан к ссылке в (const float&){2}
(сама ссылка является Lvalue!). Я думаю, что это простое правило точно описывает правила.
Стандартная сноска С++ в отношении преобразования lvalue в rvalue говорит (немного устаревшая, поскольку в нее не были внесены изменения, указывающие типы массивов)
В С++ класс prvalues может иметь cv-квалифицированные типы (потому что они являются объектами). Это отличается от ISO C, в котором не-lvalues никогда не имеют cv-квалифицированных типов.
Таким образом, более глубокая причина, по которой decltype((const int)0)
по-прежнему является типом int
, заключается в том, что она не относится к объекту. Так как нет объекта, нет ничего, чтобы сделать const, и, следовательно, выражение никогда не будет const.
Ответ 2
[intro.object]
:
Конструкции в программе на С++ создают, уничтожают, ссылаются, обрабатывают и обрабатывают объекты. Объект - это область хранения. [Примечание. Функция не является объектом, независимо от того, занимает она или нет хранилище так, как это делают объекты. -end note] Объект создается определением (3.1), новым выражением (5.3.4) или реализацией (12.2), когда это необходимо.
Итак, "значение, не связанное с объектом" - это нечто, созданное не по определению или с помощью нового выражения, что также означает, что у него нет соответствующей области хранения, например, литерала.
Изменить: За исключением строковых литералов (см. комментарии)
Ответ 3
Эта цитата не так точно сформулирована, как может быть:
Значение r (так называемое, исторически, поскольку rvalues может отображаться в правой части выражения присваивания) является xvalue, временным объектом (12.2) или подобъектом или значением, которое не связано с объектом.
Значение r является выражением, поэтому оно не может быть объектом (временным или иным). Цель раздела этой цитаты, говорящего о временных объектах, состоит в том, чтобы сказать, что значение, полученное в результате оценки rvalue, является временным объектом и т.д.
Это общий ярлык, например. с int x;
мы бы случайно сказали "x is in int", когда на самом деле x
является идентификатором; и выражение x
имеет тип int
и обозначает int.
В любом случае, он делит возможные значения на три категории:
- xvalue
- временный объект
- Значение, не связанное с объектом
Определение временного объекта включает в себя объект типа класса, поэтому мне кажется, что "значение, не связанное с объектом" должно быть любым не-значением неклассического типа. Например 1 + 1
.