当前位置: 首页 > 知识库问答 >
问题:

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

郏博瀚
2023-03-14

我目前正在尝试创建一个二叉树,其中的每个节点都包含一个指向树中其他节点的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]);
    }  
}

我不喜欢使用shared_ptr,因为实际上没有任何共享所有权,这将大大降低函数的速度。

我确信这是一个我没有正确考虑的设计问题。任何帮助我如何解决这个问题都是感激的。

共有1个答案

李华茂
2023-03-14

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

当使用move语义时,您需要确保访问了被移动的对象。在这种情况下,只需重新排序语句就可以解决问题。此外,我建议使用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]);
}
const std::unique_ptr<Symbol>& ParentSymbol::GetChild(size_t index)
{
    return m_children[index];
}

再次注意,如果子列表的长度被修改,该引用可能会变得不可用,因此您可能希望使用std::unique_ptr::getunique_ptr对象中“提取”信息。或者,您可以直接返回一个非智能指针。

 类似资料:
  • 在我的Fedora 34环境(g)中,定义为: 如果表达式已经是右值,那么

  • 问题内容: 我已经有一个现有的数据库,其中包含很多表和很多数据。我打算创建一个应用程序,并与它一起使用sqlalchemy。现在,我在irc上查询了一下,然后在Google上环顾了一下,并尝试了以下想法: 首先,我使用sqlacodegen从我的生成模型DB。但是后来我对此有些困惑,然后又看了一些。我发现了这个。 这看起来是一个优雅的解决方案。 因此,第二,我models.py 我查看了文档,但对

  • 首先通过了解它们(指std::move和std::forward)不做什么来认识std::move和std::forward是非常有用的。std::move不move任何东西。std::forward也不转发任何东西。在运行时,他们什么都不做。不产生可执行代码,一个比特/Users/shikunfeng/Documents/neteaseWork/timeline_15_05_18/src/mai

  • 我正在用Java创建一个二叉搜索树,它是从一个已经实现的二叉树扩展而来的,但是当我尝试使用一些继承的方法时,它不起作用。让我解释一下: 二叉树: 英国夏令时: 应用程序: 如果我尝试打印它,它将只打印根(4),其余节点将为空。当我看看里面发生了什么,结果发现有两个根源: BST. Node根,其中包含按正确顺序排列的所有节点 BinaryTree。节点根,仅包含根,所有其他节点均为空。 所以我猜它

  • 我不知道这些节点是否被插入,但输出结果是正确的。我只想插入节点到左边的孩子,我可以消除那代码吗?root.right=insertLevelOrder(arr,root.right,2*i+2); 还有为什么这个循环没有“i++”的符号,int i是如何自动增加的?

  • 我不知道如何创建以下内容: 我总是得到 /usr/include/c/5.5.0/bits/stl_对。h:139:45:错误:使用已删除的函数'std::atomic::atomic(const std::atomic 我已经试过了 我知道std::atomic是不可复制的,那么你应该如何创建一对呢?难道这不可能吗?