如何围绕std::move构建unique_ptrs的二叉树



我目前正在尝试创建一个二叉树,其中每个节点都包含一个指向树中其他节点的unique_ptr。我的问题是关于设计的:我不完全确定如何编写一个递归函数,该函数可以在不对节点中包含的指针调用move的情况下构建这样的树,以便将它们作为参数传递给下一个递归功能调用。

我有一个看起来像这样的函数:

void MParser::parseExpression(unique_ptr<Symbol>& parent, string expression){
Scope mainScope = findMainScope(expression);
unique_ptr<Symbol> child;

if (mainScope.type == ScopeType::Atomic){
child = buildAtom(expression);
parent->appendChild(child);
return;
}else{
child = buildOperation(mainScope.type);
parent->appendChild(child);
vector<string> operands = separateOperands(mainScope, expression);
parseExpression(child, operands[0]);
parseExpression(child operands[1]);
}  
}

问题是,我的appendChild((函数涉及一个std::vector.push_back((,它要求用std::move((来移动传入的子对象。现在还可以,子节点已经被推到树的正确位置。然而,这个函数中的子变量现在是一个nullptr,当我试图将它传递到下一个函数调用时,我会得到不希望的行为。

另一个问题是,如果我实现一个getter方法来从树中检索子节点,并将其带回函数的范围,那么它也必须被移动,因此它在树中的父节点将指向nullptr。

我宁愿不使用shared_ptr,因为实际上没有任何共享所有权,这会大大降低功能的速度。

我确信这是一个我没有正确思考的设计问题。如果能帮我解决这个问题,我们将不胜感激。

问题是,我的appendChild()函数涉及一个std::vector.push_back(),它要求传入的子级与std::move()一起移动。现在还可以,子节点已经被推到树的正确位置。然而,这个函数中的子变量现在是一个nullptr,当我试图将它传递到下一个函数调用时,我会得到不希望的行为。

使用移动语义时,需要确保已完成对被移动对象的访问。在这种情况下,只需重新排序语句就可以了。此外,我建议使用std::vector::emplace_back直接调用move构造函数,而不使用默认构造函数+move赋值。

}else{
child = buildOperation(mainScope.type);
vector<string> operands = separateOperands(mainScope, expression);
parseExpression(child, operands[0]);
parseExpression(child operands[1]);
parent->appendChild(child);
}

或者,您可以让appendChild返回一个对新构建的节点的常量引用;只要确保在使用引用时永远不要添加更多的子项。

}else{
child = buildOperation(mainScope.type);
const std::unique_ptr<Symbol>& currentChildHolder = parent->appendChild(child);
vector<string> operands = separateOperands(mainScope, expression);
parseExpression(currentChildHolder, operands[0]);
parseExpression(currentChildHolder, operands[1]);
}

另一个问题是,如果我实现一个getter方法来从树中检索子节点,并将其带回函数的范围,那么它也必须被移动,因此它在树中的父节点将指向nullptr。

返回常量引用。这允许在不分配新对象的情况下访问节点,例如:

const std::unique_ptr<Symbol>& ParentSymbol::GetChild(size_t index)
{
return m_children[index];
}

再次注意,如果子项列表的长度被修改,则该引用可能变得不可用,因此您可能想要";提取物";使用CCD_ 7从CCD_。或者,您可以直接返回一个非智能指针。

相关内容

  • 没有找到相关文章

最新更新