【问题标题】:C++ no known conversion for argument 1 from ‘Node*’ to ‘Node*&’C++ 没有已知的参数 1 从‘Node*’到‘Node*&’的转换
【发布时间】:2015-06-06 01:57:57
【问题描述】:

我正在尝试使用递归函数将节点插入到二叉搜索树中。但是,当我尝试调用我的函数时,我收到错误消息

no known conversion for argument 1 from ‘Node*’ to ‘Node*&’

这是递归函数和调用它的函数的代码:

bool BST::add(int data)
{
    if (root == NULL)
    {
        Node* gnu = new Node(data);
        root = gnu;
        return true;
    }
    return recursiveAdd(root, data);
}

bool BST::recursiveAdd(Node*& start, int data)
{
    if (start == NULL)
    {
        Node* gnu = new Node(data);
        start = gnu;
        return true;
    }
    if (data < start->getData())
    {
        return recursiveAdd(start->getLeft(), data);
    }
    if (data > start->getData())
    {
        return recursiveAdd(start->getRight(), data);
    }
    if (data == start->getData())
    {
        return false;
    }
    return false;
}

以下是我的 Node 类中用于 getLeft()、getRight() 和 getData() 的函数:

 int Node::getData()
{
    return data;
}

Node* Node::getLeft()
{
    return leftChild;
}

Node* Node::getRight()
{
    return rightChild;
}

如果有人能告诉我我需要修复什么才能使其正常工作,我将不胜感激。

谢谢!

【问题讨论】:

    标签: c++ pointers binary-search-tree pass-by-reference


    【解决方案1】:

    您不能将临时变量(getLeft 和 getRight 返回的副本)与非 const 左值引用绑定,因此会出现错误。

    无论如何,您都不需要修改指针本身。我建议您重写您的算法以使其在没有这个相当奇怪且容易出错的要求的情况下工作。

    【讨论】:

    • 如何在不修改至少一个指针的情况下更改树的结构?
    • @Ben Voigt 与二传手?
    • @Ben Voigt 是的,当然,我的意思是通过引用直接修改它。您应该使用您正在使用的类提供的接口。
    【解决方案2】:

    您的访问器返回内部指针的副本

    Node* Node::getLeft()
    {
        return leftChild;
    }
    
    Node* Node::getRight()
    {
        return rightChild;
    }
    

    但是recursiveAdd需要能够修改结构

    start = gnu;
    

    这些方法不兼容,你很幸运编译器抓住了你。您可以更改getLeft()getRight() 以返回引用,或者捕获recursiveAdd() 所做的结构更改并使用mutator 传播它。

    Node* theLeft = start->getLeft();
    bool did_insert = recursiveAdd(theLeft, data);
    start->setLeft(theLeft);
    return did_insert;
    

    或者,正如马特所说,您可以将recursiveAdd 加为朋友,然后就这样做

    return recursiveAdd(start->leftChild, data);
    

    【讨论】:

    • 我要补充一点,拥有 getLeftgetRight 返回引用是毫无意义的,将 leftChildrightChild 公开(或让 BST 成为节点)
    【解决方案3】:
    ...
        if (root == NULL)
        {
            Node* gnu = new Node(data);
            root = gnu;
            return true;
        }
        return recursiveAdd(root, data);
    }
    

    块范围。如果 root 为 NULL,那么您最终将不会在块外声明 root。这意味着recursiveAdd() 将使用无效参数调用;这无法编译,否则它总是有机会产生未定义的行为。

    不管怎样,因为root 会过期,所以引用也会过期,因为引用会指向一个临时对象。这是不正确的,因为引用不能绑定到临时对象——根据定义,它们将指向“值的容器”,在 C++11 用语中通常称为 lvalues

    还有右值,但这不在问题的范围内。

    【讨论】:

    • 更加努力地思考人生。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-07-29
    • 2023-03-11
    • 2020-08-26
    • 2016-11-30
    • 1970-01-01
    • 2020-06-08
    相关资源
    最近更新 更多