Template class - Compilation problem

M

Marcelo

Hi everybody,
This is my first time with the template class and I have an strange problem. I
have spent all the afternoon trying to understand it, but I don't get the problem...


I have three files:

matrix.cpp (template class)
matrix.h
test.cpp

when I compile as:
g++ -I . *.cpp -shared -o test.so //There is no problem

if I compile as:
g++ -I . *.cpp -o test.o //There is no problem

Then i get this strange message:
g++ -I . *.cpp -o test.o
/tmp/ccrI7vlF.o: In function `main':
test.cpp:(.text+0x77): undefined reference to `Matrix<float>::Matrix(unsigned int)'
collect2: ld returned 1 exit status

I don't know why I get this problem. My main file is:

int main(){
Matrix<float> *vect;
(*vect) = Matrix<float>(3);
}


Can you give my some help ?
THANKS A LOT,

Marcelo

PS: I am attaching the files if someone wants to get a closer view to my
template class.
 
T

TB

Marcelo sade:
Hi everybody,
This is my first time with the template class and I have an strange
problem. I have spent all the afternoon trying to understand it, but I
don't get the problem...


I have three files:

matrix.cpp (template class)
matrix.h
test.cpp

when I compile as:
g++ -I . *.cpp -shared -o test.so //There is no problem

if I compile as:
g++ -I . *.cpp -o test.o //There is no problem

Then i get this strange message:
g++ -I . *.cpp -o test.o
/tmp/ccrI7vlF.o: In function `main':
test.cpp:(.text+0x77): undefined reference to
`Matrix<float>::Matrix(unsigned int)'
collect2: ld returned 1 exit status

I don't know why I get this problem. My main file is:
<code snipped>

See a few hours earlier thread "template in error"
http://groups.google.com/group/comp...hread/15cad158cc1e3858/f946e213be3e61b3?hl=en

TB
 
P

Paul Henderson

when I compile as:
g++ -I . *.cpp -shared -o test.so //There is no problem
Then i get this strange message:
g++ -I . *.cpp -o test.o
test.cpp:(.text+0x77): undefined reference to `Matrix<float>::Matrix(unsigned int)'

As the template is in a different source file from the main() function,
it is compiled separately. So, the compiler doesn't know it needs to
instantiate a Matrix<float> form of the template at the time when it is
actually building the template; hence, this is not created and you have
an unresolved external. If you compile with -shared, the linker is
happy to believe that the symbol might be resolved by linking against
something that provides it sometime later, so no error appears at this
stage, but if you compile to an executable, you're left with a missing
symbol.

To solve it, either put your template class in the same translation
unit as the stuff using it, or use an explicit instantiation in
matrix.cpp, like "template class Matrix<float>;" which will cause the
compiler to instantiate the required form. That'll also show you a
number of errors in the matrix code (which never actually got compiled
before). Finally, in your 'main', you set the value of vect, but it
isn't pointing anywhere in particular, so you'll get undefined
behaviour (probably a segfault).
 
N

Neo

Marcelo,

You are trying to deploy what we would ( in strict C++ ) terms call
as "Template Separation Compilation Model" i.e; to keep template
signature & actual implementation in separate files.

Since g++ still doesn't implement the "export" keyword, the only way
out is to be fall-back on "Template Inclusion Compilation Model" which
is a compile time overhead or else explicitly instantiate the class
instances from outside the main.cpp file.

You may put the same in the translation unit carrying implementation
of that Matrix constructor.

But well, of-course if you are trying to build libraries then only
way is "Template Inclusion Compilation Model"!
 
V

Victor Bazarov

Neo said:
You are trying to deploy what we would ( in strict C++ ) terms call
as "Template Separation Compilation Model" i.e; to keep template
signature & actual implementation in separate files.

Since g++ still doesn't implement the "export" keyword, the only way
out is to be fall-back on "Template Inclusion Compilation Model" which
is a compile time overhead or else explicitly instantiate the class
instances from outside the main.cpp file.

You may put the same in the translation unit carrying implementation
of that Matrix constructor.

But well, of-course if you are trying to build libraries then only
way is "Template Inclusion Compilation Model"!

There is another option.

If the library developer knows that the template is going to be used
only for a [relatively small] limited set of template arguments, the
templates can be instantiated during building of the library by means
of _explicit_instantiation_. Simply declare (explicitly instantiate)
every possible template when compiling the library. The code will be
generated and placed in the library where later the linker will find
it while trying to resolve references in the user's code.

Look up "explicit instantiation" in the news archives, I am certain
you can find the details of what I am talking about.

V
 

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

Forum statistics

Threads
473,769
Messages
2,569,580
Members
45,054
Latest member
TrimKetoBoost

Latest Threads

Top