0

Possible Duplicate:
Why can templates only be implemented in the header file?

I am trying to practice C++ templates and while doing it, g++ gave me the following linker error:

g++ main.o list.o -o app
main.o: In function `main':
main.cpp:(.text+0x27): undefined reference to `List<int>::List(List<int> const&)'
collect2: ld returned 1 exit status
make: *** [app] Error 1

I tried to do the following in my main :

#include "List.h"

int main() {
    List<int> a;
    List<int> b(a);
    return 0;
}

while my List.h looks like :

#ifndef LST_H
#define LST_H

template <typename T>
class List {
    public:
    template <typename TT> class Node;
    private:
    Node<T> *head;
    public:
    List() { head = new Node<T>; }
    ~List() { delete head; }
    List( const List &l );

    template <bool DIM> class iterable_frame;
    template <bool DIM> class supervised_frame {
        iterable_frame<DIM> sentinels;
        iterable_frame<DIM> data;
        bool sentinel_completeness;

        public:
        supervised_frame( const List& );
        ~supervised_frame() {}
        void copy_sentinels( iterable_frame<DIM>& );
        void copy_cells( iterable_frame<DIM>& );
    };
    template <bool DIM> class iterable_frame {
        Node<T> *head;
        Node<T> *caret;

        public:
        iterable_frame( const List& );
        ~iterable_frame() {}
        inline bool end() { return head == caret; }
    };
    template <typename TT> class Node {
        unsigned index[2];
        TT num;
        Node<TT> *next[2];
        public:
        Node( unsigned x = 0, unsigned y = 0 ) { index[0]=x; index[1]=y; next[0] = this; next[1] = this; }
        Node( unsigned x, unsigned y, TT d ) { index[0]=x; index[1]=y; num=d; next[0] = this; next[1] = this; }
        ~Node() {}
        friend class List;
    };
};

#endif

and my List.cpp like :

#include <iostream>
#include "List.h"

template <typename T>
List<T>::List( const List<T> &l ) {
    head = new Node<T>;
    iterable_frame<1> in(l);
    supervised_frame<1> out(*this);
}

template <typename T> template <bool DIM>
List<T>::supervised_frame<DIM>::supervised_frame( const List<T> &l  ) {
    std::cout << DIM << std::endl;
}
template <typename T> template <bool DIM>
void List<T>::supervised_frame<DIM>::copy_sentinels( iterable_frame<DIM>& ) {}
template <typename T> template <bool DIM>
void List<T>::supervised_frame<DIM>::copy_cells( iterable_frame<DIM>& ) {}

template <typename T> template <bool DIM>
List<T>::iterable_frame<DIM>::iterable_frame( const List<T> &l ) {
    std::cout << '\t' << DIM << std::endl;
}

The code is still draft-like, but I'll explain a bit my intentions. The idea behind was that I wanted to have a class List that could act as a sparse matrix, so I make first template to easily switch between the number types stored (int, float etc.). Then I create two auxiliary iterator-like classes for handling the elements, that are implemented by templates too, because the direction of the iteration can be twofold - column-wise or row-wise and the different matrix methods would choose one that serves them best. And the list is to be a two dimensional ring.

Community
  • 1
  • 1
infoholic_anonymous
  • 969
  • 3
  • 12
  • 34
  • you should inclue the list.cpp into the list.h. the list.cpp can't been compiled separately. – bbg Dec 06 '12 at 01:26
  • @infoholic_anonymous nope, don't include cpp files. You can rename it to something else (.impl) and include that, but not cpp files. – Luchian Grigore Dec 06 '12 at 01:34

1 Answers1

1

The only copy constructor you have declared in your class definition is:

List( const List &l );

and it has no visible implementation (being a template and all), ergo the error. Move the implementation to the header.

Luchian Grigore
  • 253,575
  • 64
  • 457
  • 625