I’m writing a tree-like container, where each “node” has a list with branches/subtrees, currently my head looks like:
class _tree {
public:
typedef _tree* tree_ptr;
typedef std::list<_tree> _subTreeTy;
explicit _tree(const _ValTy& v, const _NameTy& n); //create a new tree
_tree(const _ValTy& v, const _NameTy& n, tree_ptr _root);
//create a new tree and add it as branch to "_root".
~_tree();
void add_branch(const _tree& branch); //add by copy
void add_branch(_tree&& branch); //add by move
private:
_subTreeTy subtrees;
_ValTy value;
_NameTy name;
};
_tree::_tree(const _ValTy& v, const _NameTy& n, tree_ptr _root)
: root(_root),
value(v),
name(n)
{
_root->add_branch(*this); //not rvalue(???)
}
Now the second constructor would create a tree inside _root – however how does this work with calling (ignore private violation):
_tree Base(0,"base");
_tree Branch(1, "branch", &Base);
Base.subtrees.begin()->value = 8;
std::cout << Branch.value;
How would I make it so that Branch & *Base.subtrees.begin() refer to the same node? Or should i go the other way. Use add_branch() to CREATE a branch/subtree?
Move semantics is about moving the internals of an object, not the object (as a typed piece of memory) itself. It’s best to think about it in terms of values and invariants, since C++ still has value semantics even when moving is taken into account. This means:
In other words, while you can convert the expression
*thisto an rvalue by doingstd::move(*this)what you want cannot be achieved right now sincestd::list<_tree>uses value semantics and_treehas value semantics itself.*Base.subtrees.begin()is a distinct object fromBranchand as things are modifications to the former won’t affect the latter.Switch to reference semantics if that’s what you want (or need), for instance by using
std::shared_ptr<_tree>andstd::enable_shared_from_this(you’d then use_root->add_branch(shared_from_this())inside the constructor). I wouldn’t recommend it though, this could get messy. Value semantics are very desirable in my opinion.With value semantics, using your tree could look like:
That is,
addBranchreturns a reference to the newly constructed node. Sprinkling some move semantics on top:Strictly speaking if
_treeis copyable move semantics are not necessary though,Base.addBranch(Tree);would work too.