编译器声明调用没有匹配的函数,即使原型中有一个

The compiler states that there's no matching function for a call, even though there is one in the prototype

本文关键字:原型 有一个 函数 调用 声明 编译器      更新时间:2023-10-16

我正在尝试实现一个二叉搜索树类,但编译器抛出错误。bstNode.h 文件在这里:

template <class Item, class Key>
class bstNode
{
public:
    bstNode();
    bstNode(const Item& init_data, const Key& init_key, bstNode<Item, Key> *init_left, bstNode<Item, Key> *init_right);
    ~bstNode();
    bstNode<Item, Key>* tree_copy(const bstNode<Item, Key>*& root);
private:
    Item data;
    Key key;
    bstNode* left;
    bstNode* right;
};
    template <class Item, class Key>
    //line 83 in the original code is below
bstNode<Item, Key>* bstNode<Item, Key>::tree_copy(const bstNode<Item, Key>*& root)
{
    bstNode<Item, Key>* l_ptr;
    bstNode<Item, Key>* r_ptr;
    if (root == NULL) return NULL;
    l_ptr = tree_copy(root -> left());
    r_ptr = tree_copy(root -> right());
    return new bstNode<Item, Key> (root -> data(), l_ptr, r_ptr);
}

.h 文件使用空的主函数编译良好,但是当我在 bstNode.cxx 中使用以下代码尝试它时,它崩溃了,给出了错误。代码为:

    #include <cstddef>
#include <algorithm>
#include <math.h>
#include <iostream>
#include "bstNode.h"
using namespace std;
int main()
{
    bstNode<int, size_t>* root_ptr = NULL;
    bstNode<int, size_t>* copy_root_ptr = root_ptr -> tree_copy(root_ptr);
    return 0;
}

错误是:

bstNode.cxx: In function ‘int main()’:
bstNode.cxx:14: error: no matching function for call to ‘bstNode<int, long unsigned int>::tree_copy(bstNode<int, long unsigned int>*&)’
bstNode.h:83: note: candidates are: bstNode<Item, Key>* bstNode<Item, Key>::tree_copy(const bstNode<Item, Key>*&) [with Item = int, Key = long unsigned int]

原型与函数的实现完全相同,没有bstNode::所以我不确定发生了什么。我正在使用 g++ 编译器。有什么想法吗?非常感谢,谢谢。

编辑:我减少了代码以尝试突出显示问题。

编译器(在大多数情况下(拒绝代码是正确的。问题是没有从T*&const T*&的转换,所以现有的函数不能使用。

为什么不存在这种转换?

这种转换不存在的原因是它会破坏常量正确性。请考虑以下示例:

const int k = 10;
void f( const int*& kp ) {
   kp = &k;                 // Fine, the pointer promises not to change the object
}
int main() {
   int *p; 
   f( p );                 // Does not compile, but assume it would
                           // after the call, p points to k
   *p = 20;                // Modifying a constant!!!!
                           //    p never promised not to change the pointee
}

现在,由于您不需要修改传递给函数的指针,因此一个可能的解决方案是向签名添加更多const

bstNode<Item, Key>* tree_copy(const bstNode<Item, Key>* const & root);

这样做会阻止代码更改指针,这是上面示例中的问题。但是,如果你真的考虑一下,

为什么要首先传递对指针的引用?

指针

的复制成本很低,因此按const&传递指针没有多大意义,并且由于您不需要该函数来更改要传递的指针,因此按值传递将既正确可能更有效。

原型并不完全相同,因为存在const差异。声明是

 bstNode<Item, Key>* tree_copy(const bstNode<Item, Key>*& root);

(引用常量指针(而您将其称为

 bstNode<int, size_t>* root_ptr;
 tree_copy(root_ptr);

所以它得到了对非常量指针的引用。虽然你可以将foo *传递给需要const foo *的东西,但你不能通过引用需要const foo * &的东西来传递foo *

相关文章: