2012-06-28 4 views
18

Часто говорят, что в C++ 11 разумно возвращать std::vector по значению.Возврат std :: vector по значению

В C++ 03 это было в основном верно, поскольку RVO должен оптимизировать копию. Но должен отпугнул большинство разработчиков.

  • В C++ 11 будет возвращена локальная переменная std::vector?
  • Что делать, если этот вектор является членом локальной переменной вместо локальной переменной?
  • Очевидно, что возврат глобальной переменной не будет перемещаться. Какие другие случаи не будут перенесены?
+0

См. Также [этот вопрос] (http://stackoverflow.com/q/9532608/500104). – Xeo

ответ

15

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

В C++ 11 всегда будет перемещена возвращаемая локальная переменная std :: vector?

Каждый раз, когда удовлетворяются критерии для копирования, или переменная явно std::move d.

Что делать, если этот вектор является членом локальной переменной вместо локальной переменной?

Он не будет перемещен, если явно не указано std::move d.

Очевидно, что возвращение глобальной переменной не будет перемещено. Какие другие случаи не будут перенесены?

Каждый раз, когда критерии для копирования не выполняются, а переменная явно не указана std::move d.

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

+0

Я не думаю, что он будет перемещен, если он может быть RVO'd. – juanchopanza

+0

@juanchopanza хорошо, да, ничто из этого не предотвращает оптимизацию. –

+0

OK; ваш первый пункт, по-видимому, подразумевает, что он ** будет перемещаться каждый раз, когда выполняются критерии для копирования. – juanchopanza

8

В C++ 11 всегда будет перемещена локальная переменная std::vector?

Для локальной переменной, даже параметр по значению, компилятор должен всегда попытка, чтобы переместить его первый (если ни движение, ни копия может быть опущены по каким-либо причинам, даже если эти критерии встретил). Если это не удается, он пытается снова с копией:

§12.8 [class.copy] p32

Когда критерии элизии операции копирования будут выполнены или будут выполнены за исключением того, что исходный объект является параметром функции, и объект, который нужно скопировать, обозначается lvalue, разрешение перегрузки для выбора конструктора для копии сначала выполняется так, как если бы объект был обозначен rvalue.Если сбой разрешения перегрузки или тип первого параметра выбранного конструктора не является ссылкой rvalue на тип объекта (возможно, cv-qualified), разрешение перегрузки выполняется снова, считая объект как lvalue. [Примечание: Это двухступенчатое разрешение перегрузки должно выполняться независимо от того, произойдет ли копирование. Он определяет вызывающий конструктор, если elision не выполняется, и выбранный конструктор должен быть доступен, даже если вызов отменяется. -end note]

Что делать, если этот вектор является членом локальной переменной вместо локальной переменной?

Субобъект не будет перемещен, поскольку это не соответствует критериям для копирования. (Который является немым, ИМХО, но вот как это в настоящее время. Я не думаю, что два должны быть связаны между собой, так как подобъектом может прекрасно быть перемещен, если он местный.)

Очевидно возвращение глобальной переменной будет не перемещаться. Какие другие случаи не будут перенесены?

Ссылка, очевидно, не будет перемещена. Кроме этого, я не могу думать ни о чем другом.

+0

Как насчет ссылки на локальную? Что, если 'std :: move' вызывается в локальном ref? –

+0

@deft_code: само по себе ссылка не будет перемещаться автоматически, похоже, что мое последнее предложение было недостаточно ясным в этом отношении. Ссылка 'std :: move''d будет перемещать выделенный объект. – Xeo

Смежные вопросы