Возврат С++ std::vector без копии?
Можно ли вернуть стандартный контейнер из функции без копирования?
Пример кода:
std::vector<A> MyFunc();
...
std::vector<A> b = MyFunc();
Насколько я понимаю, это копирует возвращаемое значение в новый вектор b. Возвращает ли функция возвращаемые ссылки или что-то подобное, чтобы избежать копирования?
Ответы
Ответ 1
Если ваш компилятор поддерживает NRVO, копия не будет выполнена при условии выполнения определенных условий в функции, возвращающей объект. К счастью, это было наконец добавлено в Visual С++ 2005 (v8.0) Это может иметь большое влияние на perf, если контейнер большой, очевидно.
Если ваш собственный компилятор не сообщает, поддерживает ли он его, вы должны скомпилировать код С++ для ассемблера (в режиме оптимизации/выпуска) и проверить, что сделано с помощью простой функции образца.
Здесь также есть более широкое обсуждение здесь
Ответ 2
Rvalues ( "temporaries" ), привязанные к const
ссылкам, будут продлеваться до конца эталонного времени жизни. Поэтому, если вам не нужно изменять этот вектор, выполните следующие действия:
const std::vector<A>& b = MyFunc();
если вам нужно изменить вектор, просто скопируйте его так, как это проще всего читать, пока у вас не будет доказательств (полученных с помощью профилирования), что эта строка даже имеет значение с точки зрения производительности.
В противном случае полагайтесь на С++ 1x с его ссылками на rvalue и двигайте семантику, которая идет "в ближайшее время" и оптимизирует ее, без необходимости делать что-либо.
Ответ 3
Если вы можете изменить подпись функции, вы можете использовать
std::vector<A>& MyFunc();
или
void MyFunc(std::vector<A>& vect);
Вы также можете вернуть умный указатель, но это включает в себя создание объекта.
some_smart_pointer<std::vector<A>> MyFunc();
НТН