This answer is designed to discuss the various approaches, explain them, and put them into context.
option 1: the native to vector copy:
vector<float> createVectorFromArray()
{
// data copied once
float myArr[10];
readDataFromSomewhere(myArr, 10);
// vectors are lightweight handles. zero-cost construction
// since the optimiser will see that the next statement assigns to
// the vector
vector<float> resVector;
//
// data copied twice
//
resVector.assign(myArr, myArr+10);
//
// it's almost guaranteed that RVO will elide this copy. As of c++17
// it's a guarantee. Returning the vector is fine
return resVector;
}
Problems:
- data copied twice
- vector will require memory allocation
option 2: use the vector directly
vector<float> createVectorFromArray()
{
// Will allocate space and
// default-initialise the floats (i.e. they won't be initialised)
vector<float> resVector(10);
//
// one data copy. perfectly safe and idiomatic.
// std::addressof expressed intent clearly.
//
readDataFromSomewhere(std::addressof(resVector[0]), resVector.size());
//
// it's almost guaranteed that RVO will elide this copy. As of c++17
// it's a guarantee. Returning the vector is efficient.
return resVector;
}
Problems:
- vector will require memory allocation
Better...
option 3 : re-use an existing vector
void createVectorFromArray(vector<float>& resVector)
{
//
// if resVector has been used before and has a capacity() of 10
// or more, no memory allocation necessary
//
resVector.resize(10);
// one copy of data
readDataFromSomewhere(std::addressof(resVector[0]), resVector.size());
}
Problems:
- perhaps not quite to easy to use the reference interface.
How would I choose between option 2 and 3?
Option 2 is more readable (IMHO) but would be expensive if used in a loop. So for a one-off, I'd go for that.
If I'm reading data into a buffer in a loop, I'd probably want to avoid un-necessary memory allocations. So re-using the vector's capacity would be a wise move.
e.g.
std::vector<float> buf;
while (thereIsMoreData())
{
createVectorFromArray(buf); // option 3
useTheData(buf);
// data no longer needed, so we can re-use the vector
}
the alternative:
while (thereIsMoreData())
{
// the passing of the vector is efficient, particularly as of c++11
// however, we still suffer one memory allocation per loop.
// probably undesirable in a high performance environment.
useTheData(createVectorFromArray()); // option 2
}
Finally...
option 4:
Provide both. Allow the user the performant approach or the 'readable' approach as he/she wishes
void createVectorFromArray(vector<float>& resVector)
{
//
// if resVector has been used before and has a capacity() of 10
// or more, no memory allocation necessary
//
resVector.resize(10);
// one copy of data
readDataFromSomewhere(std::addressof(resVector[0]), resVector.size());
}
// overload
std::vector<float> createVectorFromArray()
{
std::vector<float> result;
createVectorFromArray(result);
return result;
}
std::vectorthat simply, unless they are pointers.