C2783:无法推断出辅助函数的模板参数

问题描述 投票:0回答:1

我有一个Node和BinaryTree类:

template<typename Elem>
struct Node {
    Elem Key;
    Node <Elem>* parent = nullptr;
    Node <Elem>* left = nullptr;
    Node <Elem>* right = nullptr;

    Node(Elem k);
};

template<typename Elem>
Node<Elem>::Node(Elem k):Key{k}{}

template<typename Elem>
class BinaryTree{
public:
    class iterator; //Node<Elem>*
    iterator root;
    void insert(Elem val);
    void remove(iterator& z);
};

使用BinaryTree中的类迭代器实现为:

template<typename Elem>
class BinaryTree<Elem>::iterator{
public:
    iterator();
    iterator(Node<Elem>* p);
    Node<Elem>* curr = nullptr;

    iterator& parent(); //set curr = curr->right
    iterator& left();
    iterator& right();

    void setparent(iterator& b);//sets this.curr->parent = b.curr->parent
    void setleft(iterator& b);
    void setright(iterator& b);

    iterator& Parent(); //Creates a new iterator that points to curr->parent and returns a reference to that
    iterator& Left();
    iterator& Right();

    Elem& operator *(); // returns curr->Key
    bool operator ==(iterator& b);
    bool operator !=(iterator& b);
    void operator =(iterator& b);

};

我做了一个要在BinaryTree<Elem>::remove(iterator& z)函数中使用的最小函数,实现为:

template<typename Elem>
typename BinaryTree<Elem>::iterator & minimum(typename BinaryTree<Elem>::iterator & z) {
    while(z.Left().curr != nullptr) {
        z.left();
    }
    return z;
}

Remove函数以minimum()作为参数调用z.Right()时,给出错误C2783,该错误表示:

“ BinaryTree :: iterator&minimum(BinaryTree :: iterator&)':无法推断'Elem'的模板参数”

remove()函数实现为:

template<typename Elem>
void BinaryTree<Elem>::remove(iterator& z) {
    if (z.Left().curr == nullptr) {
        transplant(*this, z, z.Right());//The z.Right() creates a new iterator on the heap, whose curr pointer points to z.curr->right
    }

    else if (z.Right().curr != nullptr) {
        transplant(*this, z, z.Left());
    }

    else {

        iterator y = minimum(z.Right()); //-> This gives the error C2783 and C2762 (no matching overloaded function found)
        if (y.Parent() != z) {
            transplant(*this, y, z.Right());
            y.curr->right = z.curr->right;
            y.Right().curr->parent = y.curr;
        }
        transplant(*this, z, y);
        y.curr->left = z.curr->left;
        y.curr->left->parent = y.curr;
    }
}
c++ visual-studio binary-search-tree
1个回答
0
投票

在几种情况下,无法推导模板函数的参数。 ::(范围分辨率运算符)左侧有模板自变量的情况就是这种情况。

在以下情况下,类型,模板和非类型值...不参与模板参数推导,而是use在其他地方推导或明确指定的模板参数。

  1. 嵌套名称说明符(范围解析运算符::左侧的所有内容)使用限定ID指定的类型...

Source

因此,在您的示例中,函数参数中::运算符左侧的所有内容都在非推论上下文中:

template<typename Elem>
typename BinaryTree<Elem>::iterator & minimum(
    typename BinaryTree<Elem>::iterator & z
             ^^^^^^^^^^^^^^^^  ^^^^^^^^
               non-deduced     deduced
)

仅因为在这种情况下未尝试扣除,所以扣除失败。

请注意,右侧没有任何要推论的内容。但是,此示例中有:

template <typename Elem>
void foo(std::vector<Elem> const &)

在这里可以执行Elem的推论,因为它没有出现在::运算符的左侧。

最简单的解决方法只是不在乎这是否是BinaryTree<Elem>::iterator,并且只接受任何类型:

template <typename T>
T & minimum(T & z) { ... }
© www.soinside.com 2019 - 2024. All rights reserved.