Latyas
Latyas

Reputation: 35

What's wrong?undefined reference?

ERROR CODE:

    CList<CString,const char*> test;

ERROR INFO:
    ECLIPSE / UBUNTU 10

/home/latyas/workspace/CList/Debug/../test.cpp:7: undefined reference
            to `CList<CString, char const*>::CList()'

I have already defined this constructor:

template<typename T1, typename T2> CList<T1, T2>::CList() :
        m_nHead(0), m_nTail(0),m_nCount(0) {
}

Why am I getting this error?

updated:

#include <iostream>
#include "CString.h"
#include "CList.h"

int main()
{
    CList<CString,const char*> test;
    test.AddHead("test");
    return 0;
}


/*
 * CList.h
 *
 *  Created on: 2012-3-31
 *      Author: latyas
 */

#ifndef CLIST_H_
#define CLIST_H_


template<typename T1,typename T2> class CList {
public:
    struct CNode {
        CNode* pNext;
        CNode* pPrev;
        T1 data;
    };
    CList();
    ~CList();
    long GetHead();
    long GetTail();
    long GetNext(long, T1&); 
    long GetCount();
    long AddHead(T2);
    long AddTail(T2);
    long RemoveAt(long);

private:
    CNode* m_nHead;
    CNode* m_nTail;
    long m_nCount;

};

#endif /* CLIST_H_ */

/*
 * CList.cpp
 *
 *  Created on: 2012-3-31
 *      Author: latyas
 */

#include "CList.h"
#include <cstdlib>
#include <iostream>

/
template<typename T1, typename T2> CList<T1, T2>::CList() :
        m_nHead(0), m_nTail(0),m_nCount(0) {
}
template<class T1, class T2> CList<T1, T2>::~CList() {
    std::cout << "~CList()";

Upvotes: 2

Views: 314

Answers (3)

shofee
shofee

Reputation: 2129

There is no .cpp file for templated classes, so all your implementation must be done in the .h file only..

/*
 * CList.h
 */

#ifndef CLIST_H_
#define CLIST_H_


template<typename T1,typename T2> class CList {
public:
    struct CNode {
        CNode* pNext;
        CNode* pPrev;
        T1 data;
    };
    CList();
    ~CList();
    long GetHead();
    long GetTail();
    long GetNext(long, T1&); 
    long GetCount();
    long AddHead(T2);
    long AddTail(T2);
    long RemoveAt(long);

private:
    CNode* m_nHead;
    CNode* m_nTail;
    long m_nCount;

};

#endif /* CLIST_H_ */

/* ========== Implementation of Clist class ============ */

template<typename T1, typename T2> CList<T1, T2>::CList() :
        m_nHead(0), m_nTail(0),m_nCount(0) {
}
template<class T1, class T2> CList<T1, T2>::~CList() {
    std::cout << "~CList()";

Upvotes: 0

celtschk
celtschk

Reputation: 19731

You didn't say where you defined it. I guess you did so in some implementation file. However for templates the implementation has to go into the header file (unless you explicitly instantiate them for every type they might be used for).

For this, it's helpful to think of templates as a sort of type-safe macro (however note that templates are far more complex than macros, so please don't overstretch that analogy). Just like macros, templates contain instructions on how to create code; it's at a different level (macros at the textual level, templates on the syntax level), but the basic principle is the same: The template is not the code, it generates the code. A template which you never instantiate will not show up in your compiled code at all.

At the place where you define your variable test you instantiate the template CTest for the types CString and const char*. That is, you instruct the compiler to generate a concrete class CList<CString, const char*> from your CList template. However since at that place, the compiler cannot see the definition of the destructor, it cannot generate it. However it doesn't complain because it doesn't know that you didn't instantiate it elsewhere for those types. However it generates a reference to it, so that it gets called on execution.

In the implementation file, the compiler does see your constructor template, however you don't instantiate it there, therefore the compiler doesn't generate any code from it (it couldn't do so anyways because it cannot know with which types you might instantiate the class elsewhere).

Now on linking, the linker sees the reference to the constructor CList<CString, const char*>::CList() (from your file which defined test), but no definition for it (because none was generated). And therefore it complains about the missing reference.

Upvotes: 1

Black
Black

Reputation: 5080

"Undefined reference" is most likely a linker error, i.e. the linker cannot find a library referenced by Your source code.

You are using CString. Which library is it from? Is this library known to the linker?

Upvotes: 0

Related Questions