I want to fill std::vector (or some other STL container):
class Foo { public: Foo(int _n, const Bar &_m); private: std::vector<Foo> fooes_; }
1.Good looking ctor, expensive performance
std::vector<Foo> get_vector(int _n, const Bar &_m) { std::vector<Foo> ret; ... // filling ret depending from arguments return ret; } Foo::Foo(int _n, const Bar &_m) : fooes_(get_vector(_n, _m) {}
2. Better performance, worse looking ctor
void fill_vector(int _n, const Bar &_m, std::vector<Foo> &_ret) { ... // filling ret depending from arguments } Foo::Foo(int _n, const Bar &_m) { fill_vector(_n, _m, fooes_); }
Is it possible to rewrite get_vector
function from 1st example with C++0x (move semantics features and so on) to avoid redundant copying and constructor calls?
Yes, a function can return a vector in C++ and in different ways. This article explains the different ways in which a C++ function can return a vector. In order to code a vector in C++, the vector library has to be included in the program.
In C++11, this is the preferred way: std::vector<X> f(); That is, return by value. With C++11, std::vector has move-semantics, which means the local vector declared in your function will be moved on return and in some cases even the move can be elided by the compiler.
Move semantics allows you to avoid unnecessary copies when working with temporary objects that are about to evaporate, and whose resources can safely be taken from that temporary object and used by another.
std::move itself does "nothing" - it has zero side effects. It just signals to the compiler that the programmer doesn't care what happens to that object any more. i.e. it gives permission to other parts of the software to move from the object, but it doesn't require that it be moved.
If you're using a C++0x-compatible compiler and standard library, you get better performance from the first example without doing anything. The return value of get_vector(_n, _m)
is a temporary, and the move constructor for std::vector
(a constructor taking an rvalue reference) will automatically be called with no further work on your part.
In general, non-library writers won't need to use rvalue references directly; you'll just reap a decent chunk of the benefits automatically.
I believe (1) and (2) have identical performance even without C++0x, as long as your compiler does the Named Return Value Optimization, which I believe most do. Neither should do any copies, nor any moves.
Please correct me if I'm wrong, because if so I misunderstand NRVO.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With