簡體   English   中英

C2783:無法推斷幫助器 function 的模板參數

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

我有一個節點和二叉樹 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);
};

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

};

我做了一個最小的 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;
}

刪除 function 以z.Right()作為參數調用minimum()時,會給出錯誤C2783 ,其中指出:

“BinaryTree::iterator &minimum(BinaryTree::iterator &)': 無法推導出 'Elem' 的模板參數”

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

在幾種情況下,模板 function 的參數是非推導的。 :: :(范圍解析運算符)左側有一個模板參數的情況就是這樣一種情況。

在以下情況下,類型、模板和非類型值......不參與模板參數推導,而是使用在其他地方推導或明確指定的模板 arguments。

  1. 使用限定 ID 指定的類型的嵌套名稱說明符(scope 解析運算符::左側的所有內容)...

來源

因此,在您的示例中,function 參數中::運算符左側的所有內容都處於非推導上下文中:

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) { ... }

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM