Семантика перемещения - это перемещение внутренних объектов объекта, а не самого объекта (как типизированного фрагмента памяти). Лучше думать об этом с точки зрения значений и инвариантов, поскольку в C ++ семантика значений по-прежнему сохраняется, даже если учитывать перемещение Это значит:
std::unique_ptr<int> first(new int);
// invariant: '*this is either null or pointing to an object'
// current value: first is pointing to some int
assert( first != nullptr );
// move construct from first
std::unique_ptr<int> second(std::move(first));
// first and second are separate objects!
assert( &first != &second );
// New values, invariants still in place
assert( first == nullptr );
assert( second != nullptr );
// this doesn't affect first since it's a separate object
second.reset(new int);
Другими словами, хотя вы можете преобразовать выражение *this
в rvalue, выполнив std::move(*this)
, то, чего вы хотите, не может быть достигнуто прямо сейчас, поскольку std::list<_tree>
использует семантику значений, а _tree
сама имеет семантику значений. *Base.subtrees.begin()
является отличным от Branch
объектом, и, поскольку вещи являются модификациями, первое не повлияет на второе.
Переключитесь на ссылочную семантику, если это то, что вам нужно (или нужно), например, с помощью std::shared_ptr<_tree>
и std::enable_shared_from_this
(тогда вы будете использовать _root->add_branch(shared_from_this())
внутри конструктора). Я не рекомендовал бы это, хотя, это могло бы стать грязным. Семантика значения очень желательна, на мой взгляд.
При семантике значений использование вашего дерева может выглядеть следующим образом:
_tree Base(0, "base");
auto& Branch = Base.addBranch(1, "branch");
То есть addBranch
возвращает ссылку на вновь созданный узел. Опрыскивая некоторую семантику перемещения сверху:
_tree Base(0, "base");
_tree Tree(1, "branch); // construct a node not connected to Base
auto& Branch = Base.addBranch(std::move(Tree));
// The node we used to construct the branch is a separate object
assert( &Tree != &Branch );
Строго говоря, если _tree
является копируемой, то семантика перемещения не нужна, однако Base.addBranch(Tree);
также будет работать.