C ++ 11: «объявление экземпляра класса decltype» с помощью std :: move () не вызывает «конструктор перемещения». Зачем?

Я недавно начал использовать C ++ и я решил учиться C ++ 11 функции.
Но то, как работают коды с ++, иногда не так ощутимо.

ниже мой код.
На части с decltype(std::move(sample)) sample2 = std::move(sample); Я не уверен, почему эта строка не вызывает конструктор перемещения.
Не могли бы вы объяснить, почему?

#include <iostream>

class AAA
{
public:
AAA() { std::cout << "default constructor" << std::endl; }
AAA(const AAA& cs) { std::cout << "copy constructor" << std::endl; }
AAA(AAA&& cs) { std::cout << "move constructor" << std::endl; }
~AAA() { std::cout << "destructor" << std::endl; }
};

int main(int argc, char* args[])
{
AAA sample;
// ((right here))
decltype(std::move(sample)) sample2 = std::move(sample);
return 0;
}

Он скомпилирован в [ubuntu 16.04 LTS] с помощью [gcc 5.4.0]

оригинальный код: https://ide.geeksforgeeks.org/tALvLuSNbN

5

Решение

Ваш фрагмент расширяется до

AAA&& sample2 = std::move(sample);

который связывает значение (результат std::move(sample)) к значению ссылки (sample2). Новый объект не создается, и, следовательно, такой конструктор не вызывается.

6

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

Функция std::move<T> возвращает T &&, Таким образом, для std::move(sample) это возвращается AAA &&, Это Rvalue ссылка и вести себя очень как lvalue ссылка (типа как AAA & будет ссылкой на lvalue) в том смысле, что они оба являются псевдонимами для уже существующих объектов.

Важно понимать, что std::move делает не сама по себе причина чего-либо, чтобы быть перемещенным Он просто возвращает rvalue ссылку на заданный аргумент. Например std::move(foo); один не делает абсолютно ничего. Только когда результат используется для инициализации или присвоения объекту, он становится полезным.

Например auto bar = std::move(foo); вернет ссылку на значение foo и использовать эту ссылку для вызова barконструктор.

Чтобы ответить на вопрос, так как std::move(sample) возвращает AAA &&линия, о которой идет речь, такая же, как AAA && sample2 = std::move(sample);, Поведение практически такое же, как AAA & sample2 = sample;, В обоих случаях вы инициализируете ссылку на существующий объект, и новый объект создавать не нужно.

Если ваша цель — двигаться sample в новый AAAправильная строка будет auto sample2 = std::move(sample); как вы делаете с sample3, Хотя будьте осторожны, что линия sample3 движется от уже переехал sample,

6

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