возвращаемый вектор <Foo>или shared_ptr? - PullRequest
5 голосов
/ 02 ноября 2011

в функции, какой "возврат" был бы более уместным?

A.vector<Foo>?

B.shared_ptr<vector<Foor>>?

Другими словами, какая копия менее тяжелая, что бы вы сделали и почему?

Ответы [ 3 ]

6 голосов
/ 02 ноября 2011

Я думаю, что возвращение shared_ptr<vector<T>> редко полезно.Я сделал бы это только в том случае, если бы несколько объектов содержали общий вектор, которым они могли бы манипулировать.Для меня это указывает на недостаток дизайна.Лучшей альтернативой, вероятно, является возврат по константной ссылке.Это позволяет избежать (потенциально дорогостоящей) операции копирования, но не позволяет средству доступа изменять вектор.

Если вы возвращаете локальный std::vector, вы также можете вернуть его по аргументу.

Если вы действительно хотите вернуть shared_ptr<vector<T>>, подумайте, будет ли работать shared_ptr<const vector<T>> (вектор может быть проверен многими, но может быть изменен только владельцем).

Однако A обычно дороже, чем B, но здесь часто применяется оптимизация возвращаемого значения.Для C ++ 11 std::vector имеет конструктор перемещения, который гарантирует, что для возврата локального std::vector не потребуются дорогостоящие операции копирования.

Помните, не оптимизируйте преждевременно :)

2 голосов
/ 02 ноября 2011

Возврат shared_ptr<vector<Foo>> гарантирует, что дополнительное копирование не произойдет.

Возвращение vector<Foo> может избежать лишнего копирования, если активируется оптимизация возвращаемого значения (RVO) или если используется семантика перемещения из C ++ 11. Но если важно избежать копирования, я бы не использовал это (даже если вы можете гарантировать, что эти оптимизации всегда будут доступны), потому что я не думаю, что это хорошая идея - использовать семантику возврата-копии, хотя на самом деле означает не копировать .

Я бы, наверное, пошел с одним из них, но это зависит:

  • передать ссылку на vector<Foo> в качестве параметра
  • пройти итератор вставки (например, back_inserter) вместо
0 голосов
/ 03 ноября 2011

В C ++ 03 предпочитают:

  1. Если вы предоставляете доступ к члену, возвращайтесь по постоянной ссылке.
  2. Иначе, если вы возвращаете локальное значение, используйте выходной ссылочный параметр.

В C ++ 11 предпочитают:

  1. Если вы предоставляете доступ к члену, возвращайтесь по константной ссылке.
  2. Иначе, если возвращать локальный, возвращать по значению, поскольку конструкция перемещения будет избегайте чрезмерных копий.

Ситуация, когда вы захотите вернуть умный указатель с подсчетом ссылок, может быть, когда несколько объектов с непересекающимися временами жизни захотят получить доступ к объекту. Однако это не самый распространенный сценарий, но он случается достаточно часто.

...