答案:直接回傳 std::vector<MyObj> myFunction();
C++: What is the best method to return a vector of objects from a function?
Taking performance into consideration, what should be the best approach?
Return by copy:
std::vector<MyObj> myFunction();
Return by reference:
std::vector<MyObj>&
myFunction();
Return by pointer:
std::vector<MyObj>*
myFunction();
Most thankful for the explanation on what happens in each approach.
3 Answers
Sergey Zubkov,
Views
#1 is not "return by copy", it is return by value. This is the correct way to return a new vector from a function.
What happens is that, if inside the function a local variable or a temporary is returned, the compiler unifies that variable with the result of calling a function, nothing is copied, no constructors are called. This is a trivial optimization, widespread since early 1990s, which doesn't require inlining or any thinking on the part of the compiler. It is likely that C++17 will make this optimization a requirement (the proposal was reviewed favorably)
If this optimization (copy elision) is impossible, for example if you're returning a function parameter, then move constructor is executed, which, for std::vector, copies 3 pointers and the allocator if it is stateful. Prior to C++11, this would perform the expensive deep copy, so if you're targeting obsolete compilers, examine the function.
#2 returns a reference to an existing vector that must be static or managed by some other object, e.g. this could be the return of a member function returning a reference to a vector that is a member of the object on which the function was called. This is plausible, but very rare.
#3 has no use, pointers to vectors make no sense.
You're missing a few other approaches:
4. passing a vector as a reference parameter:
void myFunction(std::vector<my Obj>&);
This makes the most sense if your function both reads and modifies the vector, e.g. "sort(v);".
5. passing an output iterator:
template<class OI>
void myFunction(OI out);
This function can append to a vector if called as myFunction(back_inserter( v)); or it can overwrite a pre-sized vector if called as myFunction(v.begin()); as long as the size is provably sufficient). This makes it accept any output sequence.
What happens is that, if inside the function a local variable or a temporary is returned, the compiler unifies that variable with the result of calling a function, nothing is copied, no constructors are called. This is a trivial optimization, widespread since early 1990s, which doesn't require inlining or any thinking on the part of the compiler. It is likely that C++17 will make this optimization a requirement (the proposal was reviewed favorably)
If this optimization (copy elision) is impossible, for example if you're returning a function parameter, then move constructor is executed, which, for std::vector, copies 3 pointers and the allocator if it is stateful. Prior to C++11, this would perform the expensive deep copy, so if you're targeting obsolete compilers, examine the function.
#2 returns a reference to an existing vector that must be static or managed by some other object, e.g. this could be the return of a member function returning a reference to a vector that is a member of the object on which the function was called. This is plausible, but very rare.
#3 has no use, pointers to vectors make no sense.
You're missing a few other approaches:
4. passing a vector as a reference parameter:
void myFunction(std::vector<my
This makes the most sense if your function both reads and modifies the vector, e.g. "sort(v);".
5. passing an output iterator:
template<class OI>
void myFunction(OI out);
This function can append to a vector if called as myFunction(back_inserter(
沒有留言:
張貼留言