Поведение `xvalue` в C ++ 11/14

class Myclass
{
public:
Myclass() = default;
~Myclass() = default;
Myclass(Myclass&&) = default;
Myclass& operator=(Myclass&&) = default;

Myclass(const Myclass&) = delete;

Myclass& operator=(const Myclass&) = delete;
int i = 0;
};

Myclass GetObj()
{
Myclass obj;
return obj;
}

Myclass WrapperOfGetObj()
{
Myclass&& Wrapobj = GetObj();
Wrapobj.i = 1; // Will it work?

return std::move(Wrapobj);
}

int main()
{
return 0;
}

У меня есть несколько вопросов:
1) В WrapperOfGetObj функция, Wrapobj является xvalue, поэтому я могу присвоить значение любому члену этого (xvalue — собирается истечь !!)
2) Что такое хранение xvalue? Разве это не автоматическое хранение?
3) Когда xvalue становится glvalue и когда это станет rvalue(Любой пример в вышеприведенном контексте прояснит мне это).

2

Решение

Выражение Wrapobj это значение. Все именованные переменные являются lvalues.

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

decltype(Wrapobj) дает MyClass&&, Когда кто-то говоритWrapobj это ссылка на значение «, они говорят об объявленном типе. Но когда Wrapobj используется в выражении, имеет тип MyClass и значение категории lvalue,

Нет такого понятия, как выражение со ссылочным типом. Кроме того, категория типа и значения выражения напрямую не связана с тем, обозначает ли выражение временный объект или нет.

На ваш вопрос 2: «xvalue» — это категория значений выражений. У выражений нет памяти. Объекты имеют хранилище. Ссылки могут или не могут использовать хранилище (это неопределенные). Обязательно различайте хранение ссылки и хранение объекта, на который она ссылается.

Возвращаемое значение GetObj() это временный объект. Стандарт фактически не определяет продолжительность хранения временных объектов, хотя в общих реализациях используется стек (аналогично автоматическим объектам). Я думаю, что C ++ 17 может улучшить формулировку стандарта в этой области.

3

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

Эти ответы помогут …

Разрешают ли ссылки rvalue висячие ссылки?

Что такое rvalues, lvalues, xvalues, glvalues ​​и prvalues?

Реальные примеры xvalues, glvalues ​​и prvalues?

Myclass WrapperOfGetObj()
{
Myclass&& Wrapobj = GetObj();
Wrapobj.i = 1; // Will it work?

return std::move(Wrapobj);
}

1) В функции WrapperOfGetObj Wrapobj имеет значение xalue, поэтому я могу присвоить значение любому его члену (xvalue — срок действия истекает !!)

Wrapobj является rvalue ссылкой на prvalue, возвращаемое GetObj (). Это prvalue было расширено до времени жизни ссылки на rvalue Wrapobjтак что доступ .i = 1 Это хорошо.

2) Что такое хранилище xvalue? это не автоматическое хранение?

WrapobjОбъект, на который есть ссылка, имеет автоматическое хранение и будет уничтожен после завершения WrapperOfGetObj.

3) Когда xvalue становится glvalue и когда он становится rvalue. (Любой пример в приведенном выше контексте прояснит это мне).

xvalue — это всегда glvalues. glvalues ​​- это просто объединение всех «xvalues» и всех «lvalues» и означает «имеет идентичность». xvalues ​​также всегда являются rvalues, что является просто объединением всех «xvalues» и всех «prvalues» и означает «можно переместить».

Итак, в приведенном выше примере, Wrapobj является glvalue (поскольку он имеет идентичность), rvalue (поскольку он может быть перемещен) и xvalue (так как он является подвижным и имеет идентичность).

Когда ты вернешься std::move(Wrapobj) из WrapperOfGetObj () вы создаете новое значение prvalue из значения xvalue, возвращаемого std::move,

-1

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