Вы должны вернуться по значению.
Стандарт имеет специальную функцию, повышающую эффективность возврата по значению. Это называется «копирование elision», а точнее в этом случае «именованная оптимизация значений (NRVO)».
Компиляторы не должны его реализовывать, но затем у компиляторов есть, чтобы реализовать функцию inlining (или выполнить любую оптимизацию вообще). Но производительность стандартных библиотек может быть довольно плохой, если компиляторы не оптимизируют, и все серьезные компиляторы реализуют inlining и NRVO (и другие оптимизации).
Когда NRVO применяется, то не будет никакого копирования в следующем коде:
std::vector<int> f() {
std::vector<int> result;
... populate the vector ...
return result;
}
std::vector<int> myvec = f();
Но пользователь может хотеть сделать это:
std::vector<int> myvec;
... some time later ...
myvec = f();
Copy элизия не мешает копию здесь потому что это назначение, а не инициализация. Тем не менее, вы должны еще return by value. В C++ 11 назначение оптимизируется чем-то другим, называемым «семантикой перемещения». В C++ 03 приведенный выше код вызывает копию, и хотя теоретически оптимизатор может его избежать, на практике это слишком сложно. Таким образом, вместо myvec = f()
, в C++ 03 вы должны написать следующее:
std::vector<int> myvec;
... some time later ...
f().swap(myvec);
Существует еще один вариант, который может предложить более гибкий интерфейс для пользователя:
template <typename OutputIterator> void f(OutputIterator it) {
... write elements to the iterator like this ...
*it++ = 0;
*it++ = 1;
}
Вы можете тогда также поддерживать существующий вектор-интерфейс на вершине, что:
std::vector<int> f() {
std::vector<int> result;
f(std::back_inserter(result));
return result;
}
Это может быть менее эффективным, чем существующий код, если ваш существующий код использует reserve()
в более сложном состоянии, чем только фиксированная сумма. Но если ваш существующий код в основном называет push_back
на векторе повторно, то этот шаблонный код должен быть таким же хорошим.
Как насчет передачи вектора по ссылке, а затем заполнения его внутри 'f'? –
[RVO] (http://en.wikipedia.org/wiki/Return_value_optimization) - довольно простая оптимизация, которую большинство компиляторов сможет сделать в любой момент. –
По мере прохождения ответов он может помочь вам определить, используете ли вы C++ 03 или C++ 11. Наилучшие практики между двумя версиями варьируются довольно немного. –