Using template to implement Singly Linked List

Hi guys, I start learning data structure now. About the code , the VS compiler give me this error :
unexpected token '<', expected 'declaration' .
Please help me figure it out


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
#include<iostream>

using namespace std;
template <class T>
class SLinkedList {
public:
    class Node; // Forward declaration
protected:
    Node* head;
    Node* tail;
    int count;
public:
    SLinkedList();
    ~SLinkedList();
    void    add(const T& e);
    void    add(int index, const T& e);
    int     size();
    void toString();
public:
    class Node {
    private:
        T data;
        Node* next;
        friend class SLinkedList<T>;
    public:
        Node() {
            next = 0;
        }
        Node(Node* next) {
            this->next = next;
        }
        Node(T data, Node* next) {
            this->data = data;
            this->next = next;
        }
    };
};
template <class T>
void SLinkedList<T>::add(const T& e) {
    Node<T>* tmp = new Node<T>(e);  // this is where the error came from
    if (this->count != 0) {
        tail->next = tmp;
        tail = tail->next;
        this->count++;
    }
    else {
        head = tail = tmp;
    }
    /* Insert an element into the end of the list. */

}

template<class T>
void SLinkedList<T>::add(int index, const T& e) {
    /* Insert an element into the list at given index. */
    Node<T>* pre = head;   // this is where the error came from
    for (int i = 0; i < index - 1; i++) {
        pre = pre->next;
    }
    Node<T>* tmp = new Node<T>(e);
    tmp->next = pre->next->next;
    pre->next = tmp;
    tmp->data = e;
    this->count++;
}
template<class T>
void SLinkedList<T>::toString() {
    if (head)
        Node<T>* pRun = head;
    while (pRun) {
        cout << pRun->data << " ";
        pRun = pRun->next;
    }
}

template<class T>
int SLinkedList<T>::size() {
    /* Return the length (size) of list */
    return this->count;
}







int main() {
        SLinkedList<int> list;
        int size = 10;

        for (int index = 0; index < size; index++) {
            list.add(index);
        }
        list.toString();
        return 0;

}
   
Last edited on
In the furture please post the line numbers of the errors as well.
Here are all error from cpp.sh.
In member function 'void SLinkedList<T>::add(const T&)':
40:5: error: 'SLinkedList<T>::Node' is not a template
40:24: error: 'SLinkedList<T>::Node' is not a template
 In member function 'void SLinkedList<T>::add(int, const T&)':
56:5: error: 'SLinkedList<T>::Node' is not a template
60:5: error: 'SLinkedList<T>::Node' is not a template
60:24: error: 'SLinkedList<T>::Node' is not a template
 In member function 'void SLinkedList<T>::toString()':
69:9: error: 'SLinkedList<T>::Node' is not a template
70:12: error: 'pRun' was not declared in this scope
 In instantiation of 'void SLinkedList<T>::add(const T&) [with T = int]':
93:27:   required from here
40:33: error: no matching function for call to 'SLinkedList<int>::Node::Node(const int&)'
40:33: note: candidates are:
32:9: note: SLinkedList<T>::Node::Node(T, SLinkedList<T>::Node*) [with T = int]
32:9: note:   candidate expects 2 arguments, 1 provided
29:9: note: SLinkedList<T>::Node::Node(SLinkedList<T>::Node*) [with T = int] <near match>
29:9: note:   no known conversion for argument 1 from 'const int' to 'SLinkedList<int>::Node*'
26:9: note: SLinkedList<T>::Node::Node() [with T = int]
26:9: note:   candidate expects 0 arguments, 1 provided
20:11: note: constexpr SLinkedList<int>::Node::Node(const SLinkedList<int>::Node&)
20:11: note:   no known conversion for argument 1 from 'const int' to 'const SLinkedList<int>::Node&'
20:11: note: constexpr SLinkedList<int>::Node::Node(SLinkedList<int>::Node&&)
20:11: note:   no known conversion for argument 1 from 'const int' to 'SLinkedList<int>::Node&&'
 In instantiation of 'void SLinkedList<T>::toString() [with T = int]':
95:23:   required from here
69:18: warning: unused variable 'pRun' [-Wunused-variable]
Where? Which line of code does VS dislike?

Another compiler says:
 In member function 'void SLinkedList<T>::add(const T&)':
40:5: error: 'SLinkedList<T>::Node' is not a template
40:24: error: 'SLinkedList<T>::Node' is not a template
 In member function 'void SLinkedList<T>::add(int, const T&)':
56:5: error: 'SLinkedList<T>::Node' is not a template
60:5: error: 'SLinkedList<T>::Node' is not a template
60:24: error: 'SLinkedList<T>::Node' is not a template
 In member function 'void SLinkedList<T>::toString()':
69:9: error: 'SLinkedList<T>::Node' is not a template
70:12: error: 'pRun' was not declared in this scope
 In instantiation of 'void SLinkedList<T>::add(const T&) [with T = int]':
93:27:   required from here
40:33: error: no matching function for call to 'SLinkedList<int>::Node::Node(const int&)'
40:33: note: candidates are:
32:9: note: SLinkedList<T>::Node::Node(T, SLinkedList<T>::Node*) [with T = int]
32:9: note:   candidate expects 2 arguments, 1 provided
29:9: note: SLinkedList<T>::Node::Node(SLinkedList<T>::Node*) [with T = int] <near match>
29:9: note:   no known conversion for argument 1 from 'const int' to 'SLinkedList<int>::Node*'
26:9: note: SLinkedList<T>::Node::Node() [with T = int]
26:9: note:   candidate expects 0 arguments, 1 provided
20:11: note: constexpr SLinkedList<int>::Node::Node(const SLinkedList<int>::Node&)
20:11: note:   no known conversion for argument 1 from 'const int' to 'const SLinkedList<int>::Node&'
20:11: note: constexpr SLinkedList<int>::Node::Node(SLinkedList<int>::Node&&)
20:11: note:   no known conversion for argument 1 from 'const int' to 'SLinkedList<int>::Node&&'
 In instantiation of 'void SLinkedList<T>::toString() [with T = int]':
95:23:   required from here
69:18: warning: unused variable 'pRun' [-Wunused-variable]

Line 60 tries to construct a Node with type T argument. Your Node does not have such constructor.

Why is Node a public class and not a private struct? Struct needs no friends and users of list need no Nodes.
My VS 2019 compiler give me only 3 errors at 3 line 40,56,60. And still I don't know how to fix it, it's been 3 days since the teacher give me this excercise, and tomorrow will be the deadline. All I know is that all the code the teacher give in the excercise is unchangable, the only thing i do is the 3 functions forward the template<class T> line
You don't specify a template parameter when referencing Node. This compiles (not tried):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
#include<iostream>

using namespace std;

template <class T>
class SLinkedList {
public:
	class Node; // Forward declaration

protected:
	Node* head {};
	Node* tail {};
	int count {};

public:
	SLinkedList() {}	//REQUIRED!!!!!
	~SLinkedList() {}	//REQUIRED!!!!!

	void    add(const T& e);
	void    add(int index, const T& e);
	int     size();
	void toString();

public:
	class Node {
	private:
		T data;
		Node* next;
		friend class SLinkedList<T>;

	public:
		Node() {
			next = 0;
		}

		Node(Node* next) {
			this->next = next;
		}

		Node(T data, Node* next = nullptr) {
			this->data = data;
			this->next = next;
		}
	};
};

template <class T>
void SLinkedList<T>::add(const T& e) {
	Node* tmp = new Node(e);  // this is where the error came from
	if (this->count != 0) {
		tail->next = tmp;
		tail = tail->next;
		this->count++;
	}     else {
		head = tail = tmp;
	}
	/* Insert an element into the end of the list. */

}

template<class T>
void SLinkedList<T>::add(int index, const T& e) {
	/* Insert an element into the list at given index. */
	Node* pre = head;   // this is where the error came from
	for (int i = 0; i < index - 1; i++) {
		pre = pre->next;
	}

	Node* tmp = new Node(e);
	tmp->next = pre->next->next;
	pre->next = tmp;
	tmp->data = e;
	this->count++;
}
template<class T>
void SLinkedList<T>::toString() {
	//if (head)
		Node* pRun = head;
	while (pRun) {
		cout << pRun->data << " ";
		pRun = pRun->next;
	}
}

template<class T>
int SLinkedList<T>::size() {
	/* Return the length (size) of list */
	return this->count;
}

int main() {
	SLinkedList<int> list;
	int size = 10;

	for (int index = 0; index < size; index++) {
		list.add(index);
	}

	list.toString();
	return 0;

}


Note that you need function bodies for 2 functions.
Thanks seeplus, but now its seem to occur a new error at line 40 too. The error is :
'SLinkedList<int>::Node::Node(SLinkedList<int>::Node *)': cannot convert argument 1 from 'const T' to 'SLinkedList<int>::Node *'
Again I need your help

What I posted above compiles OK with VS2019 as C++17 - I haven't looked very closely at the code for non-compile problems or tried to run it. As posted, does this not compile with your version of VS - or have you changed it? If you're not using VS2019 then I suggest up update to this.

Note that in my code above, I changed L40 to allow a missing next pointer.
Last edited on
Sorry, my bad. The error came from line 49, same as 64 and 69. My vs version is 2019 too. And the parameter in codeline 40 cannot change due to it is my teacher's pre code. My work is in 3 function below the template<class T> line. Again, Im sorry and please help me with this one
OK. If you can't change L40, then for L49, L69 you can use:

 
Node* tmp = new Node(e, nullptr);


to get it to compile. May not be correct logic.

Don't know about L64. This is just a simple assignment and shouldn't cause an error.

Your teacher's code needs updating!

I got a new message from my teacher. Other student have the same issues. He has update it and I pass all the hiden test, thank you seeplus. You help me everything.
Topic archived. No new replies allowed.