После хорошо принятого ответа на этот вопрос Разрешают ли ссылки rvalue висячие ссылки? Казалось бы, значения xvalue не продлеваются, когда они присваиваются rvalue-ссылке lvalue, как в вопросе. Однако, когда я делаю это
#include <iostream>
using namespace std;
class Something {
public:
Something() {
cout << "Something()" << endl;
}
Something(const Something&) {
cout << "Something(const Something&)" << endl;
}
Something(Something&&) {
cout << "Something(Something&&)" << endl;
}
~Something() {
cout << "~Something()" << endl;
}
int a;
};
Something make_something() {
return Something{};
}
int main() {
auto&& something = make_something().a;
return 0;
}
Время жизни объекта, возвращаемого вызовом make_something
продлен, хотя make_something().a
является xvalue согласно http://en.cppreference.com/w/cpp/language/value_category (третья пуля в объяснении xvalues перечисляет доступ к элементу, который у меня есть выше, как xvalue,)
a.m, член выражения объекта, где a является r-значением, а m является a
нестатический элемент данных не ссылочного типа;
Если категории значений не определяют, когда время жизни значения r будет увеличено, то что тогда? Мне трудно понять, когда время жизни rvalue продлено в C ++
Увеличение продолжительности жизни не заботит категории значений. Как сказано в [class.tevent] / p6:
Временный объект, к которому привязана ссылка, или временный объект, являющийся полным объектом подобъект, к которому привязана ссылка сохраняется в течение всей жизни ссылки
Акцент добавлен.
Здесь ничего не сказано о категории значений выражения, на которое делается ссылка.
То, что определяет, является ли временный объект расширенным, является точно вышеизложенным (и еще несколькими правилами).
Но это не объясняет, почему добавление
std::move()
вокруг временного, которому назначается ссылка, не продлевает срок службы
std::move
не магическая, определяемая компилятором конструкция в C ++. Это вызов функции, и, следовательно, он ведет себя не иначе, как любой другой вызов функции C ++.
Итак, если у вас есть std::move(Type())
, что это значит? Это означает, что вы создадите временный, привязать его к параметр std::move
, затем вызовите эту функцию, которая будет возвращать что-то.
Привязка временного к параметру функции, как указано в [class.teditional] / p6, означает, что время жизни временного объекта устанавливается равным времени жизни полного выражения, которое его создало (если не для этого правила, то временное будет должны быть уничтожены в конце вызова функции, так как это конец времени жизни ссылки).
Неважно, что функция делает, говорит или подразумевает. Неважно, может ли компилятор встроить что-либо и определить, что возвращаемое значение является ссылкой на аргумент, полученный из временного объекта. Время жизни этого временного фиксированного выражения, а не расширенного.
Если категории значений не определяют, когда время жизни значения r будет увеличено, то что тогда? Мне трудно понять, когда время жизни rvalue продлено в C ++
Обратите внимание, что категории значений описывают выражения не объекты. Категории значений (xvalue, prvalue или что-либо еще) не будут расширяться каким-либо образом. Только объекты могут иметь жизнь.
Из стандартного чертежа n4296:
Временные файлы типа класса создаются в различных контекстах: привязка ссылки к prvalue (8.5.3), возврат
prvalue (6.6.3), преобразование, которое создает prvalue (4.1, 5.2.9, 5.2.11, 5.4), выбрасывая исключение (15.1),
и в некоторых инициализациях (8.5).
а также
Существует два контекста, в которых временные уничтожаются в другой точке, чем конец полного
выражение. […] Второй контекст, когда ссылка связана с временным. Временный, на который ссылается
связаны или временный, то есть полный объект подобъекта, к которому привязана ссылка, сохраняется
за время существования ссылки
Примечание: я не цитировал первый контекст, так как он имеет незначительное отношение к вопросам. Курсив выделен мной.
Таким образом категория стоимости функции выражение makesomething()
это prvalue
создание временного типа класса, согласно первому абзацу, указанному выше.
makesomething().a
доступ временный, полный субобъект. Привязка этого временного к эталонным выводам, согласно второй контекст цитируется выше, для продления срока службы.
Время жизни подобъекта a
связан со временем жизни предыдущего созданного временного, что делает его истекающее значение (Xvalue). Без продления времени жизни путем привязки его к ссылке он будет уничтожен вместе с временным объектом класса. Таким образом, в этом случае после ;
,