Compilation with Templates

A

Ajay Daptardar

Hi,

I have the following problem. Consider this:

// codec.h
template <class T>
class codec {
public:
codec(T val);
private:
T val;
};

// codec.cpp
#include "codec.h"
template <class T>
codec<T>::codec(T val) { this->val = val; }

// main.cpp
#include "codec.h"
void main() { codec<int> cc(7); }

I compile using: c++ codec.cpp main.cpp
and I get:
/tmp/ccwlkOaV.o: In function `main':
/tmp/ccwlkOaV.o(.text+0x10): undefined reference to `codec<int>::codec(int)'
collect2: ld returned 1 exit status

But if I either move the contents of codec.cpp to the codec.h file OR
move the main to codec.cpp, everything works out. Why ?

Is there a way to make this work having the three files that I have ?

Thanks -
 
R

Ron Natalie

Ajay Daptardar said:
But if I either move the contents of codec.cpp to the codec.h file OR
move the main to codec.cpp, everything works out. Why ?

Is there a way to make this work having the three files that I have ?
Most of the compilers out there can't handle separate compilation of templates.
Even if they did, you'd need to explicitly declare it as an exported template
(which you don't do). .

-Ron

main must return int, by the way.
 
R

Rob Williscroft

Ajay Daptardar wrote in
Hi,

I have the following problem. Consider this:

// codec.h
template <class T>
class codec {
public:
codec(T val);
private:
T val;
};

// codec.cpp
#include "codec.h"
template <class T>
codec<T>::codec(T val) { this->val = val; }

// main.cpp
#include "codec.h"
void main() { codec<int> cc(7); }

I compile using: c++ codec.cpp main.cpp
and I get:
/tmp/ccwlkOaV.o: In function `main':
/tmp/ccwlkOaV.o(.text+0x10): undefined reference to
`codec<int>::codec(int)' collect2: ld returned 1 exit status

But if I either move the contents of codec.cpp to the codec.h file OR
move the main to codec.cpp, everything works out. Why ?

Is there a way to make this work having the three files that I have ?

You need to get a compiler that supports export (comaeu is currently
the only one) and readup on how to use it, or put the defenition of
codec<T>::codec(T val) in the header (.h) file.

templates aren't instantiated until you actually use them, and then
only if the compiler has seen a defenition.

In your example the compiler instantiates codec<T>::codec(T val),
with T = int, in main(), but only if its seen it already. This
doesn't happen if you have the defenition in another translation
unit (.cpp file), hence the linker failes to find it and you
get the error.

HTH.

Rob.
 
E

E. Robert Tisdale

Ajay said:
I have the following problem. Consider this:

// codec.h
template <class T>
class codec {
public:
codec(T val);
private:
T val;
};

// codec.cpp
#include "codec.h"
template <class T>
codec<T>::codec(T val) { this->val = val; }

template class codec said:
// main.cpp
#include "codec.h"
int main(int argc, char* argv[]) { codec<int> cc(7); return 0; }

I compile using: c++ codec.cpp main.cpp and I get:

/tmp/ccwlkOaV.o: In function `main':
/tmp/ccwlkOaV.o(.text+0x10): undefined reference to `codec<int>::codec(int)'
collect2: ld returned 1 exit status
But if I either move the contents of codec.cpp to the codec.h file OR
move the main to codec.cpp, everything works out. Why?

Because the entire class template definition
including template <class T> codec<T>::codec(T val)
was available to your compiler when it instantiated codec said:
Is there a way to make this work having the three files that I have?

You should instantiate template class codec<int> *explicitly*
in codec.cpp
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
474,159
Messages
2,570,879
Members
47,416
Latest member
LionelQ387

Latest Threads

Top