Почему вы используете std:: move, когда у вас есть && в C++11? [дубликат]




Возможные Дубликаты:
может кто-нибудь объяснить мне семантику перемещения?






недавно я присутствовал на семинаре C++11, и был дан следующий лакомый кусочек совета.



when you have && and you are unsure, you will almost always use std::move


может ли кто-нибудь объяснить мне, почему вы должны использовать std::move в отличие от некоторых альтернатив, а в некоторых случаях, когда вы не должны использовать std::move?

589   4  

4 ответов:

во-первых, есть, вероятно, неправильное представление в вопросе, который я рассмотрю:
Всякий раз, когда вы видите T&& t в коде (и T-это тип, а не тип шаблона), имейте в виду категорию, стоимостью t является lvalue (ссылка), а не rvalue(временный) больше. Это очень запутанно. Элемент T&& означает, что t и построен от объекта, который был rvalue 1, а t является lvalue, а не rvalue. Если это имеет имя (в данном случае, t) тогда это значение lvalue и не будет автоматически перемещаться, но если у него нет имени (результат 3+4) тогда это rvalue и будет автоматически перейти в его результат, если это возможно. Элемент тип (в данном случае T&&) не имеет почти никакого отношения к категории значений переменной (в данном случае lvalue).

это, как говорится, если у вас есть T&& t написано в коде, это означает, что у вас есть ссылка на переменную это был временное, и это нормально, чтобы уничтожить, если вы хотите. Если вам нужно получить доступ к переменной несколько раз, вы делаете не хотите std::move от него, иначе он потеряет свою ценность. Но в последний раз вы его не видели!--1--> безопасно std::move это значение для другого T если вы хотите. (А 95% времени, это то, что вы хотите сделать). Все это также относится к auto&& переменные.

1. если T тип шаблона , T&& вместо этого является ссылкой для пересылки, и в этом случае вы используете std::forward<T>(t) вместо std::move(t) в последний раз. Смотрите этот вопрос.

нашел в этой статье чтобы быть довольно информативным по вопросу ссылок на rvalue в целом. Он упоминает std::move к концу. Это, пожалуй, самая актуальная цитата:

мы должны использовать std::move С <utility>--std::move - это способ говоря: "хорошо, честное слово, я знаю, что у меня есть lvalue, но я хочу этого быть собой rvalue."std::move сам по себе ничего не перемещает; он просто превращает lvalue в rvalue, так что вы можете вызвать перемещение конструктор.


скажем, у вас есть конструктор перемещения, который выглядит так:

MyClass::MyClass(MyClass&& other): myMember(other.myMember)
{
    // Whatever else.
}

при использовании оператора other.myMember, возвращаемое значение является значением lvalue. Таким образом, код использует скопировать конструктор для инициализации this->myMember. Но так как это конструктор перемещения, мы знаем, что other является временным объектом, а следовательно, и его членами. Так что мы действительно хотим использовать более эффективным!--26-->движение конструктор для инициализации this->myMember. Используя std::move гарантирует, что компилятор обрабатывает other.myMember как ссылка rvalue и вызывает конструктор перемещения, как вы бы хотели:

MyClass::MyClass(MyClass&& other): myMember(std::move(other.myMember))
{
    // Whatever else.
}

просто не использовать std::move на объектах, которые вам нужно держать вокруг - перемещение конструкторов почти гарантированно испортить любые объекты, переданные в них. Вот почему они используются только с временными.

надеюсь, что это поможет!

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

как переезд не должен быть дороже, чем копирование, вы почти всегда хотите, чтобы переместить его. И, чтобы переместить его, вы должны использовать .

когда следует избегать std::move, даже если это будет безопасно? Я бы не использовал его в тривиальных примерах, например:

 int x = 0;
 int y = std::move(x);

рядом с этим, я вижу никаких минусов. Если это не усложняет код, то перемещение следует делать по возможности ИМХО.

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

return std::move(x); // not recommended

(Если Вам ПОВЕЗЕТ, оптимизация возвращаемого значения хиты, что даже лучше, чем операция перемещения.)

вы можете использовать move, когда вам нужно "перенести" содержимое объекта в другое место, не делая копию. Кроме того, объект может принимать содержимое временного объекта без копирования с помощью std::move.

оформить заказ по этой ссылке

Comments

    Ничего не найдено.