Увеличение продолжительности жизни, значения и значения

После хорошо принятого ответа на этот вопрос Разрешают ли ссылки 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 ++

2

Решение

Увеличение продолжительности жизни не заботит категории значений. Как сказано в [class.tevent] / p6:

Временный объект, к которому привязана ссылка, или временный объект, являющийся полным объектом подобъект, к которому привязана ссылка сохраняется в течение всей жизни ссылки

Акцент добавлен.

Здесь ничего не сказано о категории значений выражения, на которое делается ссылка.

То, что определяет, является ли временный объект расширенным, является точно вышеизложенным (и еще несколькими правилами).


Но это не объясняет, почему добавление std::move() вокруг временного, которому назначается ссылка, не продлевает срок службы

std::move не магическая, определяемая компилятором конструкция в C ++. Это вызов функции, и, следовательно, он ведет себя не иначе, как любой другой вызов функции C ++.

Итак, если у вас есть std::move(Type()), что это значит? Это означает, что вы создадите временный, привязать его к параметр std::move, затем вызовите эту функцию, которая будет возвращать что-то.

Привязка временного к параметру функции, как указано в [class.teditional] / p6, означает, что время жизни временного объекта устанавливается равным времени жизни полного выражения, которое его создало (если не для этого правила, то временное будет должны быть уничтожены в конце вызова функции, так как это конец времени жизни ссылки).

Неважно, что функция делает, говорит или подразумевает. Неважно, может ли компилятор встроить что-либо и определить, что возвращаемое значение является ссылкой на аргумент, полученный из временного объекта. Время жизни этого временного фиксированного выражения, а не расширенного.

4

Другие решения

Если категории значений не определяют, когда время жизни значения r будет увеличено, то что тогда? Мне трудно понять, когда время жизни rvalue продлено в C ++

Обратите внимание, что категории значений описывают выражения не объекты. Категории значений (xvalue, prvalue или что-либо еще) не будут расширяться каким-либо образом. Только объекты могут иметь жизнь.

Из стандартного чертежа n4296:

  • §12.2.1

    Временные файлы типа класса создаются в различных контекстах: привязка ссылки к prvalue (8.5.3), возврат
    prvalue (6.6.3), преобразование, которое создает prvalue (4.1, 5.2.9, 5.2.11, 5.4), выбрасывая исключение (15.1),
    и в некоторых инициализациях (8.5).

а также

  • §12.2.4

    Существует два контекста, в которых временные уничтожаются в другой точке, чем конец полного
    выражение. […] Второй контекст, когда ссылка связана с временным. Временный, на который ссылается
    связаны или временный, то есть полный объект подобъекта, к которому привязана ссылка, сохраняется
    за время существования ссылки

Примечание: я не цитировал первый контекст, так как он имеет незначительное отношение к вопросам. Курсив выделен мной.

Таким образом категория стоимости функции выражение makesomething() это prvalue создание временного типа класса, согласно первому абзацу, указанному выше.
makesomething().a доступ временный, полный субобъект. Привязка этого временного к эталонным выводам, согласно второй контекст цитируется выше, для продления срока службы.


Время жизни подобъекта a связан со временем жизни предыдущего созданного временного, что делает его истекающее значение (Xvalue). Без продления времени жизни путем привязки его к ссылке он будет уничтожен вместе с временным объектом класса. Таким образом, в этом случае после ;,

1

По вопросам рекламы [email protected]