935
935

Reputation: 59

Error: Invalid use of non-static data member, variable was not declared in this scope

The following is an internal nested class within a templated class for a skiplist. I get the error: "height was not declared in this scope" at the line declaring *next.

        class Node{
            public:
                Node(int height){
                    this->height = height;
                }
                Node(Key_t key, Mapped_t obj, int height){
                    value = std::make_pair(key, obj);
                    this->height = height;
                }
                SkipList<Key_t, Mapped_t>::Node *next[height];
                int getHeight(){return height;}
                Key_t getKey(){return value.first;}
                Mapped_t getObj(){return value.second;}
            private:
                std::pair<Key_t, Mapped_t> value;
                int height;
        };

Moving the declaration of value and height before everything else, as follows, changes the error to "invalid use of non-static data member.

         class Node{
                private:
                    std::pair<Key_t, Mapped_t> value;
                    int height;
                public:
                    Node(int height){
                        this->height = height;
                    }
                    Node(Key_t key, Mapped_t obj, int height){
                        value = std::make_pair(key, obj);
                        this->height = height;
                    }
                    SkipList<Key_t, Mapped_t>::Node *next[height];
                    int getHeight(){return height;}
                    Key_t getKey(){return value.first;}
                    Mapped_t getObj(){return value.second;}
            };

I'm at a loss as for what to do to solve this. Here is the entire class:

template <class Key_t, class Mapped_t>
class SkipList{
public:
    SkipList(int prob, int max){
        probOutOf100 = prob;
        maxHeight = max;
        head = new SkipList<Key_t, Mapped_t>::Node(maxHeight);
        tail = new SkipList<Key_t, Mapped_t>::Node(maxHeight);
        for(int i = 0; i < maxHeight; i++){
            head->next[i] = tail;
        }
    }
    ~SkipList(){
        delete head;
        delete tail;
    }

    class Node{
        public:
            Node(int height){
                this->height = height;
            }
            Node(Key_t key, Mapped_t obj, int height){
                value = std::make_pair(key, obj);
                this->height = height;
            }
            SkipList<Key_t, Mapped_t>::Node *next[height];
            int getHeight(){return height;}
            Key_t getKey(){return value.first;}
            Mapped_t getObj(){return value.second;}
        private:
            std::pair<Key_t, Mapped_t> value;
            int height;
    };

    Node *head;
    Node *tail;
    int probOutOf100;
    int maxHeight;
}

Upvotes: 0

Views: 3366

Answers (2)

user4581301
user4581301

Reputation: 33931

Problem 1

You can't use what the compiler hasn't seen yet, so moving the declaration above the usage solves this problem. You've done this already. Good job.

Problem 2

height will not be known until the object is constructed. You can't construct the object if the size of the object is not known, and height determines the size of next which contributes to the size of the object. Catch 22.

Recommend using a std::vector in place of the array and initializing the vector with height in the constructors's Member Initializer Lists. Example:

std::vector<SkipList<Key_t, Mapped_t>::Node *> next;

Node(int height): height(height), next(height)
{
}
Node(Key_t key, Mapped_t obj, int height): 
    value(std::make_pair(key, obj)),
    height(height), 
    next(height)
{
}

Upvotes: 1

R Sahu
R Sahu

Reputation: 206567

In the line below

SkipList<Key_t, Mapped_t>::Node *next[height];

you are attempting to declare an array of pointers. However, you cannot do that unless height is known at compile time.

You may want to change it to a vector and initialize it at run time.

std::vector<SkipList<Key_t, Mapped_t>::Node*> next;


...

Node(int height) : next(height) {
    this->height = height;
}

PS I am not sure what data structure uses an array of pointers as the "next" nodes of a node. Just something to think about.

Upvotes: 2

Related Questions