patterncppMinor
Canonical Implementation of Move Semantics
Viewed 0 times
movecanonicalimplementationsemantics
Problem
I am trying to compose an illustrative example which shows how to implement move semantics on an object that will be stored in a
Please consider the following code, which is my illustrative example so far. It is designed to be a canonical, pedantically correct implementation of an object that implements move semantics, does not implement copy semantics, and can be stored in a
vector.Please consider the following code, which is my illustrative example so far. It is designed to be a canonical, pedantically correct implementation of an object that implements move semantics, does not implement copy semantics, and can be stored in a
vector<> (Where T is Moveable, below). How did I do?#include
#include
#include
#include
#include
#include
#include
using namespace std;
class Moveable
{
public:
string foo_;
string bar_;
Moveable(Moveable&& rhs) : foo_(std::move(rhs.foo_)), bar_(std::move(rhs.bar_)) {} // move construction
Moveable(const string& foo) : foo_(foo) {}; // convert construction
Moveable& operator=(Moveable&& rhs) // move assignment
{
foo_ = std::move(rhs.foo_);
bar_ = std::move(rhs.bar_);
return * this;
}
private:
Moveable(const Moveable&); // not defined, not copy-constructible
Moveable& operator=(const Moveable&); // not defined, not copy-assignable
Moveable(); // not defined, not default constructible
};
Moveable generate_it()
{
static string foo ;
if( foo.empty() || foo[0] == 'z' )
foo.insert(0, 1, 'a');
else
foo[0]++;
return foo;
}
int main()
{
typedef vector Moveables;
Moveables v;
generate_n(back_inserter(v), 1024, &generate_it);
cout bool
{
return it.foo_ == target;
});
if( that != v.end() )
v.erase(that);
sort(v.begin(), v.end(), [](const Moveables::value_type& lhs, const Moveables::value_type& rhs) -> bool
{
return lhs.foo_ > rhs.foo_;
});
cout << v.size() << endl;
}Solution
-
One small error: Mark the move constructor as
-
Why is the destructor virtual? If the example is supposed to be minimal then this might be distracting.
-
In
The
-
The
-
Finally, in the
One small error: Mark the move constructor as
noexcept, otherwise there are situations where it won’t be used. The linked case is different since the class has a copy-constructor, yet I can imagine that there are still situations where it matters, especially since your copycon isn’t deleted, just private and undefined.-
Why is the destructor virtual? If the example is supposed to be minimal then this might be distracting.
-
In
generate_it:return std::move(Moveable(foo));The
std::move here is redundant, since you are returning a temporary. What’s more, the explicit constructor call is redundant too, since the constructor isn’t marked as explicit. Just return foo; will do.-
The
find_if call could be replaced by vanilla find, using temporary construction again:auto that = find(v.begin(), v.end(), target);-
Finally, in the
sort call, why aren’t the arguments declared const&? Granted, makes the line even longer as it stands this is inconsistent with the const-correctness illustrated in the find_if call.Code Snippets
return std::move(Moveable(foo));auto that = find(v.begin(), v.end(), target);Context
StackExchange Code Review Q#12954, answer score: 6
Revisions (0)
No revisions yet.