Какое значение не связано с объектом?

Стандарт C ++ 11 и C ++ 14 (и рабочий проект соответственно) говорят в §3.10.1:

Prvalue («чистое» rvalue) - это rvalue, не являющееся значением x. [Пример: результатом вызова функции, возвращаемый тип которой не является ссылкой, является prvalue. Значение литерала, такого как 12, 7.3e5 или true, также является prvalue. —Конечный пример]

а также

Rvalue (исторически так называемое, потому что rvalue может появляться в правой части выражения присваивания) - это xvalue, временный объект (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. [...]


person gha.st    schedule 04.09.2014    source источник
comment
Выражения, отличные от lvalue, возвращают значения, а не объекты.   -  person Keith Thompson    schedule 05.09.2014
comment
@KeithThompson Итак, выражение prvalue, которое дает временный объект, не дает объект? запутался   -  person gha.st    schedule 05.09.2014
comment
Я не совсем уверен; Я знаю C лучше, чем C ++, а в C есть только lvalues ​​и non-lvalues. В любом случае значение выражения 42 - это prvalue, не связанное с объектом; оценка 42 не создает int объект.   -  person Keith Thompson    schedule 05.09.2014
comment
Я сразу думаю, что nullptr, true, this и т. Д. Могут быть значениями без объекта, но я не уверен.   -  person Mooing Duck    schedule 05.09.2014
comment
@KeithThompson Я добавил некоторые сложности со ссылками на вопрос, который возникает, когда 42 не создает временный объект.   -  person gha.st    schedule 05.09.2014
comment
@ gha.st Справочные части работают через последний пункт [dcl.init.ref] / 5: в противном случае создается временный объект типа «cv1 T1» [...] То есть , int const& x = 3; создает временный (объект), инициализированный с помощью 3, и связывает этот объект со ссылкой. Изменить: Ах, я только что видел, как вы уже обсуждали это в комментариях к ответу Антона.   -  person dyp    schedule 05.09.2014


Ответы (3)


Примерами таких значений являются все не-массивные, неклассовые не временные prvalue (временное prvalue соответствует временному объекту). Примеры включают 2.0 и 1. Контрпримеры включают "hello" (который является массивом), std::string("haha") (который является объектом класса) или float prvalue, временно инициализированным из 2, который привязан к ссылке в (const float&){2} (сама ссылка является lvalue!). Я думаю, что это простое правило точно охватывает правила.

В сноске стандарта C ++ о преобразовании lvalue в rvalue говорится (немного устарело, потому что в него не были внесены поправки для упоминания типов массивов)

В классе C ++ prvalues ​​могут иметь типы с квалификацией cv (поскольку они являются объектами). Это отличается от ISO C, в котором значения, отличные от lvalue, никогда не имеют типов с квалификацией cv.

Таким образом, более глубокая причина того, что decltype((const int)0) все еще относится к типу int, заключается в том, что он не ссылается на объект. Итак, поскольку объекта нет, нечего делать const, и, следовательно, выражение тоже никогда не будет const.

person Johannes Schaub - litb    schedule 05.09.2014

[intro.object]:

Конструкции в программе C ++ создают, уничтожают, обращаются к объектам, обращаются к ним и манипулируют ими. Объект - это область хранения. [Примечание: функция не является объектом, независимо от того, занимает ли она память, как это делают объекты. - конец примечания] Объект создается определением (3.1), новым выражением (5.3.4) или реализацией (12.2), когда это необходимо.

Итак, «значение, не связанное с объектом» - это что-то, созданное не по определению или с помощью new-expression, что также означает, что оно не имеет соответствующей области хранения, например, литерала.

Изменить: кроме строковых литералов (см. комментарии)

person Anton Savin    schedule 04.09.2014
comment
Строковые литералы - это lvalue (§5.1.1.1) - не будет ли это определение означать, что они не являются объектами (что противоречит определению lvalue) и не имеют соответствующей области хранения? - person gha.st; 05.09.2014
comment
@ gha.st: строковые литералы - это l-значения. Я считаю, что Антон имел в виду целочисленные литералы и литералы с плавающей запятой. - person Mooing Duck; 05.09.2014
comment
@MooingDuck Строковые литералы не создаются ни определением, ни новым выражением, что заставляет меня подозревать, что это может быть немного больше, чем кажется (ну, по крайней мере, моим) глазом - person gha.st; 05.09.2014
comment
@ gha.st Я думаю, что здесь может быть пробел в стандарте. Если строковый литерал является lvalue, это должен быть объект, и, конечно же, с ним связана область хранения, потому что вы можете назначить ему указатель const char*. - person Anton Savin; 05.09.2014
comment
@AntonSavin: Я почти уверен, что вы не можете присвоить const char* строковому литералу ... - person Mooing Duck; 05.09.2014
comment
@MooingDuck const char* p = "hello world"; - person Anton Savin; 05.09.2014
comment
int&& x = 3; должно быть невозможно, если 3 не вызывает создание объекта (см. Редактирование вопроса 1). - person gha.st; 05.09.2014
comment
@ gha.st 3 не вызывает создание объекта, но привязка ссылки делает - person Cubbi; 05.09.2014
comment
@Cubbi Я вижу, что это справедливо только для типов классов. Не могли бы вы подробнее рассказать об этом для неклассовых типов, которые мы здесь рассматриваем? - person gha.st; 05.09.2014
comment
@ gha.st Это описано в 8.5.3/5 ближе к концу. И 12.2 ссылается на 8.5 как на возможный источник временных файлов. - person Anton Savin; 05.09.2014

Эта цитата сформулирована не так точно, как могла бы быть:

Rvalue (исторически так называемые, потому что rvalue могли появляться в правой части выражения присваивания) - это xvalue, временный объект (12.2) или его подобъект, либо значение, не связанное с объектом.

Rvalue - это выражение, поэтому оно не может быть объектом (временным или каким-либо другим образом). Цель раздела этой цитаты, посвященного временным объектам, состоит в том, чтобы сказать, что значение, полученное в результате вычисления rvalue, является временным объектом и так далее.

Это распространенный ярлык, например с int x; мы бы случайно сказали «x находится в int», когда на самом деле x - идентификатор; а выражение x имеет тип int и обозначает int.

В любом случае, он делит возможные значения r на три категории:

  • xvalue
  • временный объект
  • значение, не связанное с объектом

Определение временного объекта включает в себя объект типа класса, поэтому мне кажется, что «значение, не связанное с объектом», должно быть любым не-x-значением неклассового типа. Например 1 + 1.

person M.M    schedule 04.09.2014
comment
Это означает, что значение, полученное в результате оценки rvalue, является временным объектом. Я не думаю, что это обязательно так. Целочисленные литералы - это rvalue-выражения, но с ними не связан ни один объект (то есть область хранения). - person dyp; 05.09.2014
comment
@dyp Тогда это не будет временный объект, согласно определению 12.2. - person M.M; 05.09.2014
comment
Извините, но я не совсем понимаю, о чем вы говорите тогда и то. - person dyp; 05.09.2014
comment
В моем комментарии? Тогда означает как следствие того, что вы сказали, и это означает целочисленный литерал, о котором вы говорите. - person M.M; 05.09.2014
comment
Ах, спасибо. - Но согласно 12.2 временных объектов типа int нет. Итак, оценивая rvalue, например как в 42 + 3, не создает объект. См. Также open-std.org/jtc1/sc22/ wg21 / docs / cwg_active.html # 943 (особенно последнее предложение). (Кроме того, значение не является объектом.) - person dyp; 05.09.2014
comment
@dyp Думаю, мы согласны. Мое предложение состоит в том, чтобы rvalue (которые не являются xvalue), которые относятся к типу класса, являются временным объектом, а которые не относятся к типу класса, являются значением, не связанным с объектом. - person M.M; 05.09.2014