简体   繁体   English

C2783:无法推断帮助器 function 的模板参数

[英]C2783: Could not deduce template argument for a helper function

I have a Node and BinaryTree class:我有一个节点和二叉树 class:

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);
};

With class iterator in BinaryTree implemented as:使用 BinaryTree 中的 class 迭代器实现为:

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);

};

I made a minimum function to be used in the BinaryTree<Elem>::remove(iterator& z) function, implemented as:我做了一个最小的 function 用于 BinaryTree BinaryTree<Elem>::remove(iterator& z) function,实现为:

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

The remove function, when it calls minimum() with z.Right() as an argument, gives the error C2783 , which states that:删除 function 以z.Right()作为参数调用minimum()时,会给出错误C2783 ,其中指出:

"BinaryTree::iterator &minimum(BinaryTree::iterator &)': could not deduce template argument for 'Elem'" “BinaryTree::iterator &minimum(BinaryTree::iterator &)': 无法推导出 'Elem' 的模板参数”

The remove() function is implemented as: remove() function 实现为:

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;
    }
}

There are several contexts in which an argument to a template function is non-deduced.在几种情况下,模板 function 的参数是非推导的。 The case where there is a template argument to the left of the :: (scope resolution operator) is one such case. :: :(范围解析运算符)左侧有一个模板参数的情况就是这样一种情况。

In the following cases, the types, templates, and non-type values... do not participate in template argument deduction, but instead use the template arguments that were either deduced elsewhere or explicitly specified.在以下情况下,类型、模板和非类型值......不参与模板参数推导,而是使用在其他地方推导或明确指定的模板 arguments。

  1. The nested-name-specifier (everything to the left of the scope resolution operator :: ) of a type that was specified using a qualified-id...使用限定 ID 指定的类型的嵌套名称说明符(scope 解析运算符::左侧的所有内容)...

( Source ) 来源

So, in your example, everything to the left of the :: operator in the function argument is in a non-deduced context:因此,在您的示例中,function 参数中::运算符左侧的所有内容都处于非推导上下文中:

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

Deduction fails simply because deduction is not attempted in this case.扣减失败只是因为在这种情况下没有尝试扣减。

Note that there is nothing to deduce on the right side.请注意,右侧没有什么可以推断的。 However, there is in this example:但是,在这个例子中有:

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

Deduction of Elem can be performed here because it does not appear to the left of the :: operator. Elem的推导可以在这里进行,因为它不会出现在::运算符的左侧。

The simplest workaround is simply to not care whether this is a BinaryTree<Elem>::iterator and just accept any type:最简单的解决方法就是不关心这是否是BinaryTree<Elem>::iterator并且只接受任何类型:

template <typename T>
T & minimum(T & z) { ... }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM