Семантика перемещения и perfect forwarding(правильная передача)
Метки move, perfect forwarding, rvalue reference, с++
По стандарту С++, временный объект можно передавать в функцию только по константной ссылке. Это вызывало некоторые осложнения, поскольку временный объект был неотличим от константного объекта, как следствие, было неясно, надо-ли сохранять объект или можно просто его просто переместить. Стандарт C++11 представляет новый вид ссылки - rvalue reference - ссылка на временный объект. Как и обычная ссылка, она может быть const и non-const. Как и обычная ссылка, она должна быть инициализирована при объявлении.
std::move()
Теперь к вопросу о возвращаемом типе. Как уже было сказано, rvalue reference по-прежнему ссылка. Следовательно, никогда не возвращайте rvalue reference на локальную переменную. Стандарт гарантирует вызов перемещающего конструктора, если он определен и нет оптимизаций со стороны компилятора. В противном случае, будет вызван копирующий конструктор, либо, при его отсутствии, будет ошибка времени компиляции. Также следует помнить, что даже при передаче rvalue reference в копирующий конструктор(к примеру), все его члены(исключение, пожалуй, могут составить примитивные типы, поскольку разницы между копированием / перемещением там нет) необходимо явно приводить к rvalue reference, чтобы не был вызван конструктор копирования. Это касается, в том числе, передачи полученного аргумента в другие функции. Объясняется это тем, что за rvalue reference скрываются реально существующие данные, которые абсолютно точно уверены в том, что они lvalue, а следовательно, и ведут себя как lvalue. Однако, бывают ситуации, когда мы не можем утверждать, что передан T&&, а не rvalue reference на T&. Да-да, шаблонная "магия" Perfect Forwarding Взглянем на код
|
Всего комментариев 4
Комментарии
-
Чето в меня тяжело ходят rvalue reference'ым (а в стандарте их целая разновидность)
Цитата:Как видим, std::move не делает ничего, кроме преобразования типа. В этом и заключается особенность перемещения - мы лишь сигнализируем о том, что данные в объекте нам больше не нужны. Взглянем на примерЗапись от alex_x_x размещена 20.10.2012 в 15:59 -
Запись от soon размещена 20.10.2012 в 17:23 -
Цитата:дарт С++11 объявляет (3.10) пять терминов: lvalue, rvalue, xvalue, а также glvalue (обобщение lvalue и xvalue) и prvalue (более узкая специализация rvalue). Базовыми терминами являются знакомые нам lvalue, rvalue и новый термин xvalue (от expiring value). Забегая вперёд – например, xvalue является результатом функции, возвращающей rvalue ссылку. То, что понималось под rvalue в C++98, в C++11 стало prvalue (в то время как rvalue обобщает xvalue и prvalue), а новый термин glvalue обобщает lvalue и xvalue. Можно (неточно, но образно) сказать, что prvalue – это то, брать адрес от чего нельзя, lvalue – от чего можно, а xvalue – от чего бесполезно.
Запись от alex_x_x размещена 20.10.2012 в 18:31 -
А, вот вы о чем. Я думал, включать или нет это в статью. Оригинал на SO. Если требуется, я могу перевести.
Запись от soon размещена 20.10.2012 в 18:59