-1

I'm making a Linked list which is generic in nature and have some basic functionality. Then I'm trying to make another template class called "Set" which is inheriting from LinkedList. But when I try to access "head" which is a Node<>* defined in Linked List. It's giving an error. My files are:

LinkedList.h

template <typename T>
struct Node {
        T data;
        Node<T> *next;
};

template <typename T>
class LinkedList {
public:
        Node<T>* head;
        int size;

        LinkedList();
        LinkedList(const LinkedList<T> &lst);
        ~LinkedList();

        Node<T>* getHead();
        Node<T>* getTail();
};

template <typename T>
class Set:public LinkedList<T> {
public:
        void insert(T item);
        friend ostream&(ostream& out, const Set<T> set)
};

and an implementation of insert is:

template <typename T>
void Set<T>::insert(T item) {
       Node<T>* temp = head;
       bool present = false;

       while (temp != NULL) {
                if (temp->data == item) {
                        present = true;
                }

                temp = temp->next;
       }

        if (present == false) {
                /*Node<T> *tail = getTail();
                Node<T>* newTail = new Node<T>(item);
                newTail->next = NULL;
                tail->next = newTail;*/
        }
}

It says:

error: "head" was not declared in this scope in line "Node<T>* temp = head"

Lightness Races in Orbit
  • 369,052
  • 73
  • 620
  • 1,021
muqsitnawaz
  • 236
  • 2
  • 8
  • We require you to tell us _what error_. – Lightness Races in Orbit Dec 06 '14 at 21:34
  • @0x499602D2 That's obviously not a duplicate. For one this OP doesn't even know that he needs to write `this->`, so how can he be asking _why_ he needs to write it? – Lightness Races in Orbit Dec 06 '14 at 21:42
  • @LightnessRacesinOrbit That's usually what we do when people have a, say, `template`/`typename` issue. Why does it not apply here? – David G Dec 06 '14 at 21:44
  • @0x499602D2: For a start, that one was deemed a C++ FAQ entry by "committee" decision; the "dupe" you identified was not. Furthermore, if we're just going to close every question we see as a duplicate of some general-reference question on the same topic but only loosely similar to the actual question asked, then what are we doing here, really? What's the point? Might as well just give people page numbers to C++ books and be done with it. – Lightness Races in Orbit Dec 06 '14 at 21:47
  • @LightnessRacesinOrbit Alrighty, reopened. – David G Dec 06 '14 at 21:47

2 Answers2

4

This C++ oddity is due to two-phase lookup and the fact that head is a dependant name (as a member of a base class that depends on the "current" class's template arguments):

[C++11: 14.6.2/3]: In the definition of a class or class template, if a base class depends on a template-parameter, the base class scope is not examined during unqualified name lookup either at the point of definition of the class template or member or during an instantiation of the class template or member. [..]

Bypass unqualified lookup by introducing this into the expression (per [C++11: 3.4.5]):

Node<T>* temp = this->head;
//              ^^^^^^

There's a longer explanation on this previous Stack Overflow answer:


Here's a minimal(ish) testcase:

#include <iostream>

template <typename T>
struct Base
{
    int x = 42;
};

template <typename T>
struct Derived : Base<T>
{
    void foo();
};

template <typename T>
void Derived<T>::foo()
{
    std::cout << x << '\n';
}

int main()
{
    Derived<void> d;
    d.foo();
}
// main.cpp: In member function 'void Derived<T>::foo()':
// main.cpp:18:18: error: 'x' was not declared in this scope
//      std::cout << x << '\n';
//                   ^

(live demo)

To fix, change foo thus:

template <typename T>
void Derived<T>::foo()
{
    std::cout << this->x << '\n';
}

(live demo)

Community
  • 1
  • 1
Lightness Races in Orbit
  • 369,052
  • 73
  • 620
  • 1,021
2

You're inheriting from a dependent base class so member access needs to be qualified with this:

Node<T>* temp = this->head;

For more information, see this thread.

Community
  • 1
  • 1
David G
  • 90,891
  • 40
  • 158
  • 247