Можно полагаться на RVO, чтобы сделать этот код простым для написания, но использование RVO также может вас укусить. RVO - это функция, зависящая от компилятора, но, что более важно, компилятор с поддержкой RVO может отключить RVO в зависимости от самого кода. Например, если вы напишите:
MyBigObject Gimme(bool condition)
{
if( condition )
return MyBigObject( oneSetOfValues );
else
return MyBigObject( anotherSetOfValues );
}
... тогда даже компилятор с поддержкой RVO не сможет оптимизировать здесь. Есть много других условий, при которых компилятор не сможет оптимизировать, и поэтому я считаю любой код, который по своей конструкции полагается на RVO для запахов производительности или функциональности.
Если вы согласитесь с тем, что одна функция должна иметь одну работу (я только это делаю), то ваша дилемма относительно того, как вернуть заполненный вектор, станет намного проще, когда вы поймете, что ваш код нарушен на уровне разработки. , Ваша функция действительно выполняет две работы: она создает вектор, а затем заполняет его. Однако, несмотря на весь этот педантизм, существует более общее и надежное решение, чем полагаться на RVO. Просто напишите функцию, которая заполняет произвольный вектор. Например:
#include <cstdlib>
#include <vector>
#include <algorithm>
#include <iostream>
using namespace std;
template<typename Iter> Iter PopulateVector(Iter it, size_t howMany)
{
for( size_t n = 0; n < howMany; ++n )
{
*(it++) = n;
}
return it;
}
int main()
{
vector<int> ints;
PopulateVector(back_inserter(ints), 42);
cout << "The vector has " << ints.size() << " elements" << endl << "and they are..." << endl;
copy(ints.begin(), ints.end(), ostream_iterator<int>(cout, " "));
cout << endl << endl;
static const size_t numOtherInts = 42;
int otherInts[numOtherInts] = {0};
PopulateVector(&otherInts[0], numOtherInts);
cout << "The other vector has " << numOtherInts << " elements" << endl << "and they are..." << endl;
copy(&otherInts[0], &otherInts[numOtherInts], ostream_iterator<int>(cout, " "));
return 0;
}