I only have access to C++03 and I often want to move a vector into a function the way you can do it in C++11. The question how to do it not to confuse the user of the code too much. So my question is how did programmers do it before C++11.
I know that vector can be "moved" using swap function. So here is what I have come up with:
class Foo
{
public:
Foo(std::vector<int>& vec)
{
using std::swap;
swap(vec, m_vec); // "move" vec into member vector
}
private:
std::vector<int> m_vec;
};
// usage:
std::vector<int> v(100, 1337);
Foo foo(v);
// v.empty() == true
The problem with this approach is that its not evident to the user that their vector will be moved into the class Foo. Is there a best practice solution to this kind of problem? Thanks in advance!
You could define a type wrapping a reference, and a function to wrap it, to give something similar to move semantics at the call site. Something along the lines of
Alternatively, Boost has a library to allow move semantics without C++11.
If I get you right, you want to "move" the vector in a class member via a constructor call.
In C++11 you would have to provide a constructor with
std::vector<T>&&
argument and callIn C++03 you can add a "named constructor" or a friend which does this job for you.
Where you could use it like this:
In this way it is clear that the vector is moved and the move-syntax does not differ that much from C++11 (although being non-generic of course).
Note that this will copy
Foo
if optimization is turned off.Sure it is possible to have move semantics in C++03.
Using Boost.Move:
Or you can write it on your own, that works with l-values, temporaries, and where
r_value_ref<T>
wrapper can be used asT&
orconst T&
thanks tooperator T&()
:Live demo link
However, it's unsafe, e.g.
r_value_ref<int> i(123); i.get() = 456;
compiles successfully, but leads to undefined behavior. Hand-written r-value-reference wrappers require a little more effort to make them perfectly safe.You may use some wrapper with explicit name:
And then
usage:
C++03 way is to use std::auto_ptr to express passing ownership of the data
std::auto_ptr in signature clearly states that data is passed inside the function, leaving call site with empty pointer, due to the nature of copying an auto_ptr.
Note the need to either disallow or explicitly define correct copy-constructing and assignment of such a class, since default copy constructor and assignment of auto_ptr is usually not what would be correct.