通过评论/答案的洞察力,我意识到我目前的方法不是处理这些事情的好主意。
我想出了一个改变的设计,我尝试使用 swap()
方法模拟“移动”操作(在这种情况下考虑它们是可互换的)。
对于任何想要更快复制(即通过交换移动)的类或容器,应该继承下面的类(直接从真实文件复制粘贴):
/*
* An empty CRTP base class for the classes which are allowing move sematics (effectively swap)
* A given class `X` must implement `void swap(X&);` method for the movement (i.e. content swapping)
* For example, `X` is deriving this class (i.e. `class X : public Movable<X> ...`)
* ... below is an illustration for how to transfer contents of an `X` object to another
* `X o1; ... X o2(o1.move()); // contents of o1 is now moved to o2`
*/
template<typename Derived>
class Movable
{
/*
* Empty constructor for normal behavior
*/
public: Movable ()
{}
/*
* Copy constructor which does nothing; without this compiler errors out !
*/
public: Movable (const Movable ©)
{}
/*
* Move constructor which will effectively call `Derived::swap()` method
* After this, the contents of the object will be moved to each other
* For syntactic sugar, it has been made `explicit`
*/
public: explicit Movable (Movable &orig)
{
(*this)(orig);
}
/*
* Moving while Not initializing object, one need to use `operator ()` and not `operator =`
* If `operator =` is used then simply `move()` part will not happen; i.e. below 2 are same:
* `obj1 = obj2.move();` and `obj1 = obj2;`
*/
public: void operator () (Movable &orig)
{
static_cast<Derived*>(this)->swap(static_cast<Derived&>(orig));
}
/*
* This method is called from `Derived` class when move sematics is intended
*/
public: Movable& move ()
{
return *this;
}
};
这里应该如何部署:
template<typename T>
struct Vector : std::vector<T>,
Movable<Vector<T> > // inherit as CRTP base
{
// ... other methods
typedef Movable<Vector<T> > Movable_;
Vector (Movable_ &orig) : Movable_(orig) {} // Declare a constructor
};
这里应该如何使用它:
Vector<A> vA1(100); // vA1 is allocated A[100]
Vector<A> vA2 = vA1; // normal copying (no change)
vA2 = vA1; // normal assignment (no change)
Vector<A> vA3(vA1.move()); // <------- "moves" contents from 'vA1' to 'vA3'
vA1(vA2.move()); // <------- "moves" contents from 'vA2' to 'vA1'
vA2 = vA3.move(); // normal copying from 'vA3' to 'vA2' ('vA3' unaffected)