Каков наилучший способ вернуть вектор из функции в С++
У меня есть функция, которая возвращает такой массив:
vector<string> GetString()
{
vector<string> s;
s.push_back("one");
s.push_back("two");
s.push_back("three");
return s;
}
и я вызываю его следующим образом:
vector<string> mystrings=GetStrings();
Я также могу реализовать его следующим образом:
void GetString(vector<string> & s)
{
s.push_back("one");
s.push_back("two");
s.push_back("three");
}
и назовите его следующим образом:
vector<string> mystrings;
GetStrings(mystrings);
Какой из них лучше?
Позволяет ли первая копировать вектор в другой? Если да, то он медленный, если вектор большой.
Ответы
Ответ 1
Какой из них лучше?
Они делают разные вещи. Используйте первый, если вам нужен вектор, содержащий только эти строки; используйте второй, если вы хотите добавить эти строки в существующий вектор.
Если вы хотите семантику первой версии, тогда это "лучше" в смысле более удобного использования правильно и сложнее использовать неправильно.
Является ли первая копия вектора другому?
В современном С++ определенно нет: возврат локальной переменной и инициализация из временного - это перемещение, а не копирование. Даже если вы застряли с компилятором pre-С++ 11, обе копии должны быть удалены. Если ваш компилятор не поддерживает семантику перемещения или копирование elision, то вам действительно нужно выбросить его.
Ответ 2
Это в значительной степени проблема личных предпочтений и любых конвенций кодирования, с которыми вам может потребоваться работать.
До С++ 11 второй подход иногда считался предпочтительным. Эффективность гарантируется, потому что нет ненужного копирования. С другой стороны, первый подход имеет потенциал (теоретически) для вызова довольно дорогого конструктора копирования.
На практике, хотя оптимизация, называемая копированием, часто избегает конструктора копирования, что означает, что производительность так же хороша в любом случае. Однако это не гарантируется, поскольку это может зависеть от таких факторов, как настройки/возможности компилятора.
В С++ 11 была введена семантика перемещения. Он предлагает альтернативный способ устранения копирования и встроен в спецификацию языка (а не является необязательной оптимизацией компилятора). С точки зрения удобочитаемости, которая может сделать первый вариант предпочтительнее, поскольку, возможно, более очевидно, что делает ваш код.