Является ли возвращаемое значение функции постоянным по умолчанию (значение)? - PullRequest
2 голосов
/ 12 декабря 2011

Я изучаю rvalue ссылки, и учебник сказал мне это:

X foo();
X x;
x = foo();

Скорее всего, было бы хорошо и гораздо эффективнее поменять указатели ресурсов (хэндлы) между x и временный, а затем пусть деструктор временного уничтожает исходный ресурс х.

Другими словами, в особом случае, когда правая часть присваивание является значением , мы хотим, чтобы оператор присваивания копии действовал как это.

Итак, означает ли это, что возвращаемые значения из функций всегда постоянны по умолчанию и, следовательно, являются значениями? Если да: всегда ли они постоянны или тоже есть исключения?

Ответы [ 5 ]

3 голосов
/ 12 декабря 2011

Rvalue-ness и constant-ness не являются синонимами, а скорее немного ортогональны.Со следующими определениями:

struct X {};
const X x;
const X f();
int X();

Мы можем классифицировать следующие выражения :

x;       // constant lvalue
f();     // constant rvalue
g();     // non-constant rvalue

По вашему конкретному вопросу: нет, не все выражения rvalue являются постоянными.

3 голосов
/ 12 декабря 2011

Итак, означает ли это, что возвращаемые значения из функций всегда постоянны по умолчанию и, следовательно, являются значениями? Если да: всегда ли они постоянны или тоже есть исключения?

Нет. Они являются значениями, если они не возвращают ссылочный тип (cv T& или cv T&&). Они постоянны, если их тип возвращаемого значения является константным.

Это означает, что возвращаемое значение из функции X foo() является rvalue (prvalue, если вы хотите new standardese ), а не константой. Более того, в выражении, подобном x = foo(), мы обычно не заботимся о том, изменяются ли временные изменения во время присваивания, что в значительной степени является идеей семантики перемещения.

1 голос
/ 12 декабря 2011

§5.2.2 / 10 (в N3225) говорится:

Вызов функции является lvalue, если тип результата является ссылочным типом lvalue или ссылкой rvalue на тип функции, xvalue, если тип результата является ссылкой rvalue на тип объекта, и prvalue в противном случае.

1 голос
/ 12 декабря 2011

См. этот предыдущий вопрос , который говорит нам, что ни выражения rvalue ни неявно не имеют типа const, ни объекты, которые они представляют, не являются неизменными по своей природе.

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

1 голос
/ 12 декабря 2011

Возможно, вы путаете типы , объекты и выражения .Только выражений имеют понятие lvalue / rvalueness.Выражение foo(); является значением типа X.Таким образом, оператор x = foo(); вызовет - если возможно - функцию-член X::operator=(X &&) из x.В противном случае он будет привязан к стандарту X::operator=(X const &), поскольку rvalues ​​привязываются к const-ссылкам.

Обратите внимание, что теоретически возможно иметь постоянные значения rval, например, если у вас была функция, объявленная как X const bar();.Тогда bar() не будет связываться с X&&, а только с X const && (а также с X const &).Однако на практике это бесполезно.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...