Возвращая c ++ std :: vector без копии? - PullRequest
29 голосов
/ 15 сентября 2010

Можно ли вернуть стандартный контейнер из функции без копирования?

Пример кода:

std::vector<A> MyFunc();

...

std::vector<A> b = MyFunc();

Насколько я понимаю, это копирует возвращаемое значение в новый вектор b. Заставляет ли функция возвращать ссылки или что-то подобное, позволяет избежать копирования?

Ответы [ 3 ]

28 голосов
/ 15 сентября 2010

Если ваш компилятор поддерживает NRVO, то копия не будет сделана, при условии соблюдения определенных условий в функции, возвращающей объект. К счастью, это было наконец добавлено в Visual C ++ 2005 (v8.0) Это может оказать значительное влияние на производительность, если контейнер большой, очевидно.

Если ваши собственные документы по компилятору не говорят, поддерживается ли он или нет, вы должны быть в состоянии скомпилировать код C ++ для ассемблера (в режиме оптимизации / выпуска) и проверить, что сделано, используя простую функцию примера.

Здесь также есть отличное более широкое обсуждение здесь

14 голосов
/ 16 сентября 2010
Срок действия

Rvalues ​​(«временных значений»), привязанных к const ссылкам, будет увеличен до конца времени жизни ссылки.Поэтому, если вам не нужно изменять этот вектор, подойдет следующее:

const std::vector<A>& b = MyFunc();

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

В противном случае полагайтесь на C ++ 1x с его ссылками на rvalue и перемещайте семантику «очень скоро сейчас» и оптимизируйте эту копию без необходимости что-либо делать.

2 голосов
/ 15 сентября 2010

Если вы можете изменить сигнатуру функции, тогда вы можете использовать

std::vector<A>& MyFunc(); 

или

void MyFunc(std::vector<A>& vect);

Вы также можете вернуть умный указатель, но для этого нужно обновить объект.

some_smart_pointer<std::vector<A>> MyFunc();

НТН

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...