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!
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.
Begin Declare a class named as vector. Declare vec of vector type. Declare a constructor of vector class. Pass a vector object v as a parameter to the constructor.
It does not require MoveInsertable for the value type. The time complexity requirement is: "constant", btw. std::vector typically stores some pointers plus the allocator. When move-constructing a std::vector , only pointers and the allocator have to be moved.
If a copy constructor, copy-assignment operator, move constructor, move-assignment operator, or destructor is explicitly declared, then: No move constructor is automatically generated. No move-assignment operator is automatically generated.
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
template <typename T> struct move_ref {
explicit move_ref(T & ref) : ref(ref) {}
T & ref;
};
template <typename T> move_ref<T> move(T & t) {return move_ref<T>(t);}
Foo(move_ref< std::vector<int> > vec)
{
using std::swap;
swap(vec.ref, m_vec); // "move" vec into member vector
}
Foo foo(move(v));
Alternatively, Boost has a library to allow move semantics without C++11.
You may use some wrapper with explicit name:
template <typename T>
class MyMove
{
public:
explicit MyMove(T& t) : t(t) {}
T& get() {return t;}
private:
T& t;
};
template <typename T>
MyMove<T> myMove(T& t) { return MyMove<T>(t); }
And then
class Foo
{
public:
Foo(MyMove<std::vector<int>> vec)
{
using std::swap;
swap(vec.get(), m_vec); // "move" vec into member vector
}
private:
std::vector<int> m_vec;
};
usage:
std::vector<int> v(100, 1337);
Foo foo(myMove(v));
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