Другие уже указывали, что при достойном (не великом, просто приличном) компиляторе оба обычно заканчивают тем, что производят идентичный код, поэтому оба дают эквивалентную производительность.
Я думаю, что стоит упомянуть один или два других момента. Во-первых, возвращение объекта официально копирует объект; даже если компилятор оптимизирует код так, чтобы копирование никогда не происходило, оно все равно не будет (или, по крайней мере, не должно) работать, если ctor для этого класса недоступен. std::vector
, безусловно, поддерживает копирование, , но вполне возможно создать класс, который вы сможете изменить, как в getIntVector
, но не вернуть, как в returnIntVector
.
Во-вторых, и, что гораздо важнее, я бы вообще рекомендовал не использовать или из них. Вместо того, чтобы передавать или возвращать (ссылку на) вектор, вы обычно должны работать с итератором (или двумя). В этом случае у вас есть пара совершенно разумных вариантов - вы можете использовать либо специальный итератор, либо создать небольшой алгоритм. Версия итератора будет выглядеть примерно так:
#ifndef GEN_SEQ_INCLUDED_
#define GEN_SEQ_INCLUDED_
#include <iterator>
template <class T>
class sequence : public std::iterator<std::forward_iterator_tag, T>
{
T val;
public:
sequence(T init) : val(init) {}
T operator *() { return val; }
sequence &operator++() { ++val; return *this; }
bool operator!=(sequence const &other) { return val != other.val; }
};
template <class T>
sequence<T> gen_seq(T const &val) {
return sequence<T>(val);
}
#endif
Вы бы использовали это примерно так:
#include "gen_seq"
std::vector<int> vecInts(gen_seq(0), gen_seq(10));
Хотя можно утверждать, что это (своего рода) немного нарушает концепцию итераторов, я все же нахожу это предпочтительным по практическим соображениям - это позволяет вам создавать инициализированный вектор вместо создания пустого вектора и затем заполнять его позже .
Альтернатива алгоритма будет выглядеть примерно так:
template <class T, class OutIt>
class fill_seq_n(OutIt result, T num, T start = 0) {
for (T i = start; i != num-start; ++i) {
*result = i;
++result;
}
}
... и вы бы использовали что-то вроде этого:
std::vector<int> vecInts;
fill_seq_n(std::back_inserter(vecInts), 10);
Вы также можете использовать функциональный объект с std::generate_n
, но, по крайней мере, IMO, это обычно приводит к большим проблемам, чем оно того стоит.
Пока мы говорим о таких вещах, я бы также заменил это:
for(unsigned int ui = 0; ui < vecInts2.size(); ui++)
cout << vecInts2[ui] << endl;
... с чем-то вроде этого:
std::copy(vecInts2.begin(), vecInts2.end(),
std::ostream_iterator<int>(std::cout, "\n"));