【问题标题】:Invalid use of non-static data member while using templates使用模板时无效使用非静态数据成员
【发布时间】:2015-07-16 13:22:57
【问题描述】:

我截取了以下代码,它使用模板实现了二叉搜索树:

#include<iostream>
using namespace std;

template<typename T>
class Node{
    public:
    T data;
    Node<T> *left;
    Node<T> *right;
    Node<T> *parent;

    Node(T input_data=NULL){
        data=input_data;
        left=NULL;
        right=NULL;
        parent =NULL;    
    }
};



template<typename T>
class BinarySearchTree{
    private:
    long n;
    Node<T> *root;


    public:
    BinarySearchTree(Node<T> *input_root=NULL, long input_size=0){
        n=input_size;
        root=input_root;
    } 

    void insert(Node<T> *p=root, T  data){
        Node<T> *par=NULL;
        while(p!=NULL){
            par=p;
            if(data <= p->data)
                p=p->left;
            else 
                p=p->right;
        }
        Node<T> *z=new Node<T>(data);
        if(root==NULL){
            root=z;
            n=1;
            return;
        }
        z->parent=par;
        if(data<=par->data)
            par->left=z;
        else
            par->right=z;

        n+=1;                
    }

    void inorder(Node<T> *p=root){
        if(p){
            inorder(p->left);
            cout<<p->data<<" ";
            inorder(p->right);
        }
    }

int main(){
    BinarySearchTree<int> *t=new BinarySearchTree<int>();
    t->insert(5);
    t->insert(15);
    t->insert(3);
    t->insert(14);
    t->insert(25);
    t->insert(10);
    t->inorder();

}

第 27 行(即 Node *root;)出现编译错误,内容为:“非静态数据成员 'BinarySearchTree::root' 的使用无效”。我认为这与我在函数“insert”和“inorder”中包含的默认参数有关,因为当我删除默认参数“root”时我没有收到错误。

我的问题是,发生了什么,我该如何解决?如果可能的话,我想保留 root 的默认参数。

如果重要的话,我在 Windows 8.1 上使用名为“Quincy 2005”的软件进行编译(出于某些原因)。

【问题讨论】:

    标签: c++ templates default-arguments


    【解决方案1】:

    默认值必须是文字,而不是变量名。

    此外,具有默认值的参数必须在参数列表的最后。

    相当使用:

    void insert(Node<T> *p, T data) { ... }
    
    // overload with only one argument
    void insert(T data)
    {
        insert(root, data)
    }
    

    【讨论】:

    • “默认值必须是文字”我认为这不是真的。来自标准:"int g(int x = f(a)); // 默认参数:f(::a)" .f(a) 显然不是文字。
    • 默认值必须在最后(+1),但默认值不必是文字(-1)。它们不能是非静态数据成员。
    • @Barry but my Node *root;是非静态的。发生了什么事?
    • @abhidivekar 没错。默认参数不能是非静态数据成员。 root 是一个非静态数据成员。
    • @Barry:好的,我明白了。措辞让我困惑了一秒钟:p
    【解决方案2】:

    在一行如

    void insert( Node<T>* p = root ,T data ) {...}
    

    有 2 个错误。

    首先,您只能对从最后一个参数开始并向后的参数使用默认值。 由于你没有给数据一个默认值,这是一个错误(解决方案重新排序参数,那些没有默认值的必须先出现)。

    其次,root 的值是this 的成员,在声明时没有this。 解决方案,如果您需要一个默认值,请使用 nullptr 作为默认值,并在您的函数测试中为 nullptr 使用,如果需要,请改用 root。

    【讨论】:

    • 是的,我在代码的最终实现中这样做了。它工作得很好,但我很好奇这背后的理论是什么。
    猜你喜欢
    • 1970-01-01
    • 2014-01-22
    • 1970-01-01
    • 1970-01-01
    • 2014-11-08
    • 2016-01-12
    • 2023-03-12
    • 2013-10-14
    • 2015-06-26
    相关资源
    最近更新 更多