Каков наилучший способ вернуть вектор из функции в С++

У меня есть функция, которая возвращает такой массив:

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 была введена семантика перемещения. Он предлагает альтернативный способ устранения копирования и встроен в спецификацию языка (а не является необязательной оптимизацией компилятора). С точки зрения удобочитаемости, которая может сделать первый вариант предпочтительнее, поскольку, возможно, более очевидно, что делает ваш код.