LinkList node template with multiple types

I am trying to create a LinkList node class template that has multiple types. This is what I have for the node class template:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
template <class T1, class T2> 
class ListNode
{
	private:
		T1 nodeName;
		T2 value1;
		T2 value2;
		T2 value3;
		ListNode<T1,T2> *next;
		
        public: 
              //Constructors
              //Mutators
              // etc... 


The idea being that you could have the class use strings and doubles or char and ints. This is the code for the LinkList class template:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
template <class T>
class LinkList
{
	private:
		
		template <class T1, class T2>
		ListNode<T1,T2> *head;
		
	public:
		//***Constructor***
		LinkList();
		
		//***Destructor***
		~LinkList();
		
                //***LinkList Operations***
		template <class T, class T1, class T2>
		void appendNode(T1,T2,T2,T2);


One of the first problems I'm having is the declaration of a ListNode pointer in the LinkList template. The error I get is:

Error 1 error C3857: 'LinkList<T>::head': multiple template parameter  lists are not allowed	


I'm not sure if there is anything that I can do about this. I d'ont think that I can declare the Linknode this wayListNode<T> *head; and it still work with two data types. I'm having other issues but I figured that I should at least see if I'm going about this the right way. Any ideas, or pointers is greatly appreciated.
Last edited on
So, your ListNode type makes some sort of sense to me. It takes two types, the first of which is the type of the name and the second of which is the type of each of the three values at that node. Conceptually, I don't understand, then, why the linked list itself can have only one type. The node has two types, so where are they going to come from?

As for the problem itself, when you are declaring head it needs to have a type, and temple<...>... is not a type. ListNode<string, double> or ListNode<string, T> are types.

For your appendNode() method, too, I am at a loss as to what all those types are meant to represent. Should appendNode not just take a node to append to the end of the list?
I guess I'm not understanding the liklist template concept. To my understanding the linklist only needs one type (which in this case is the LinkNode class template, but could be another class that has 4 member variables and one of those that needs to be a different type). Is this correct? I admit that I may be looking at this wrong. The appendNode function accepts the user defined data as an argument and creates a new node that it then appends to the end of the list. The T is for the LinkList template type, the T1 and T2 are for the LinkNode types:

1
2
3
template <class T, class T1, class T2>
void LinkList<T>::appendNode(T1 newNN, T2 newV1, T2 newV2, T2 newV3)
{


The compiler gives me an error on this one also. Says :

Error 1 error C2244: 'LinkList<T>::appendNode' : unable to match function definition to an existing declaration


I really appreciate your help with this. I'd like to see if and how this could be done.
Do you understand how templates themselves work? If not, try seeing this article first: http://www.cplusplus.com/doc/tutorial/templates/

Let me show you a small example:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
// This will be our node. The type T will be
// the type of the value that it holds.
template<typename T>
class ListNode<T> {
    T value; // we have a value of type T
    ListNode<T>* next; // and the next value will be another node with the same type of value
};

// The list class only needs one type; the type it will be storing.
// List<int> will be a linked list of ints, and so on.
template<typename T>
class List<T> {
    // a list is defined by it's head
    // since this is a list of type T, we want nodes with values of type T
    ListNode<T>* head;

    // ... methods ...
    // an example append
    // this takes a value of type T
    void append(T val_to_append);
};


As I wrote this, I came to understand what the purpose of T1 and the three T2s is for your append, but I'm still not sure how LinkList is supposed to use T to derive the type of the internal node, since it needs two types.
I feel like I understand them. The example you gave me is very similar to ones I have seen before. This is hard for me to explain so here is the code for creating a LinkList I have in my main program for the LinkList:

LinkList<ListNode<string,int>> ListA;

ListNode is the data type (in this case its a class) for LinkList (this is what T is for). ListNode class has data types string (T1) and int(T2). Basically I want to make a link list of ListNode class that has two data types. I guess I don't understand how the syntax goes for writing a template of a class that uses a different class template as its data type(where the differnt class has two data types). If that makes sense.

Am I far off on this one? Is this even possible?
Now that I wrote that though, theoretically LinkList template should be able to accept any class that uses two data types:

LinkList<differntClass> ListA;

Where differntClass has member variables of string and double. This is what I'm tying to accomplish anyway.
Last edited on
So Ive tried creating the link list using a class node that is not a template(but still has two data types) and I'm still having trouble getting this to work. Really I just want to make a link list template that can work with classes that have two (or more) different data types. Would definitely appreciate any input anyone has.
> Really I just want to make a link list template that can work with classes
> that have two (or more) different data types.

Something along these lines
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
#include <iostream>
#include <initializer_list>
#include <string>
#include <utility>

template < typename T > struct list
{
    using value_type = T ;
    // many more typedefs
    
    list() = default ;
    list( std::initializer_list<T> il ) { for( const auto& v : il ) push_back(v) ; }
    // other foundation operators
    
    bool empty() const { return sz == 0 ; }
    // other inspectors
    
    void push_back( const T& v ) 
    {
        if( empty() ) first = last = new node(v) ;
        else
        {
            last->next = new node( v, last ) ;
            last = last->next ;
        }
        ++sz ;
    }
    
    template < typename CALLABLE > void for_each( CALLABLE fn ) const 
    { for( auto p = first ; p ; p = p->next ) fn( const_cast<T&>(p->value) ) ; }
   
    template < typename CALLABLE > void for_each( CALLABLE fn )
    { for( auto p = first ; p ; p = p->next ) fn(p->value) ; }
    
   // many more member functions
   
   
   private: 
        struct node
        {
            explicit node( const T& v ) : value(v) {}
            explicit node( const T& v, node* p, node* n = nullptr ) : value(v), next(n), prev(p) {} 
            T value ;
            node* next= nullptr ;
            node* prev = nullptr ;
        };
        
        node* first = nullptr ;
        node* last = nullptr ;
        std::size_t sz = 0 ;
}; 

int main()
{
    // class with three data types
    struct A { int i ; std::string str ; double d ; /* more member variables */ };
    
    list<A> lst { { 0, "zero", 0.12 }, { 1, "one", 1.23 }, { 2, "two", 2.34 } } ;
    lst.push_back( { 3, "three", 3.45 } ) ;
    
    lst.for_each( []( const A& a ) { std::cout << '{' << a.i << ',' << a.str << ',' << a.d << "} " ; } ) ;
    std::cout << '\n' ;
    
    list< std::pair< int, char > > another_list ; // list of template class with two data types
    another_list.push_back( { 99, '*' } ) ;
    // etc.
}

http://coliru.stacked-crooked.com/a/423d3ec66aa20e43
Thank you JLBorges! I think this is what I'm looking for. I'm not completely familiar with all the syntax but I'm going to dig through this example and analyze it to figure out how exactly it works. This is a great starting point! Once i get it figured out I will try to write my own version. If (most likely when) i have problems I'll definitely post them here. Thanks again!
Topic archived. No new replies allowed.