I need to get this straight. With the code below here:
vector<unsigned long long int> getAllNumbersInString(string line){
vector<unsigned long long int> v;
string word;
stringstream stream(line);
unsigned long long int num;
while(getline(stream, word, ',')){
num = atol(word.c_str());
v.push_back(num);
}
return v;
}
This sample code simply turns an input string into a series of unsigned long long int stored in vector.
In this case above, if I have another function calls this function, and we appear to have about 100,000 elements in the vector, does this mean, when we return it, a new vector will be created and will have elements created identically to the one in the function, and then the original vector in the function will be eliminated upon returning? Is my understanding correct so far?
Normally, I will write the code in such a way that all functions will return pointer when it comes to containers, however, program design-wise, and with my understanding above, should we always return a pointer when it comes to container?
The
std::vectorwill most likely (if your compiler optimizations are turned on) be constructed directly in the function’s return value. This is known as copy/move elision and is an optimization the compiler is allowed to make:This quote is taken from the C++11 standard but is similar for C++03. It is important to note that copy/move elision does not have to occur at all – it is entirely up to the compiler. Most modern compilers will handle your example with no problems at all.
If elision does not occur, C++11 will still provide you with a further benefit over C++03:
In C++03, without copy elision, returning a
std::vectorlike this would have involved, as you say, copying all of the elements over to the returned object and then destroyed the localstd::vector.In C++11, the
std::vectorwill be moved out of the function. Moving allows the returnedstd::vectorto steal the contents of thestd::vectorthat is about to be destroyed. This is much more efficient that copying the contents over.You may have expected that the object would just be copied because it is an lvalue, but there is a special rule that makes copies like this first be considered as moves:
As for whether you should return a pointer to your container: the answer is almost certainly no. You shouldn’t be passing around pointers unless its completely necessary, and when it is necessary, you’re much better off using smart pointers. As we’ve seen, in your case it’s not necessary at all because there’s little to no overhead in passing it by value.