Подтвердить что ты не робот

Возврат std::vector по значению

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

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

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

Ответ 1

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

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

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

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

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

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

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

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

Ответ 2

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

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

§12.8 [class.copy] p32

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

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

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

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

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