HowTo make template class part of static library?

M

Matt

I'm posting this question for one of my developers who's not quite as
newsgroup-savvy. Any suggestions?

The question follows, along with relevant source code.

-Matt

I have a templated queue class as part of a statically linkable
library (in GQueue.h and .cpp below). The library compiles fine, but
when I go to use it in an executable, I get linker errors complaining
that it can not find references for any of the queue functions. I
compile just the queue class as an object file, and then perform 'nm'
on the queue object and it returns the following:

00000000 b .bss
00000000 d .data
00000000 t .text

No functions in the object file. I hard coded the queue as a string
queue and everything works fine. How can I get the templated version
to generate a valid object file so that I can leave the queue
templated and still use it in a static library rather that directly
compiling it with the executable?

---------------- GQueue.h -----------------
#ifndef GQUEUE_H
#define GQUEUE_H

#include <string>
#include <queue>

using namespace std;

template <class QE>
class GQueue
{
public:

GQueue();
~GQueue();

void push(QE element);
QE pop();
int size();

private:

queue<QE> data;
};

#endif


---------------- GQueue.cpp -----------------
#include "GQueue.h"

template <class QE>
GQueue<QE>::GQueue()
{
}

template <class QE>
GQueue<QE>::~GQueue()
{
}

template <class QE>
void GQueue<QE>::push(QE element)
{
data.push(element);
}

template <class QE>
QE GQueue<QE>::pop()
{
QE tmp = data.front();
data.pop();
return tmp;
}

template <class QE>
int GQueue<QE>::size()
{
int size = data.size();
return size;
}
 
M

Matt

I forgot to mention:

This problem happens with gcc in both a Windows-MingW and Redhat-Linux
environment. I don't know the gcc version at the moment.

Please let me know if more info is required.

-Matt
 
J

John Harrison

Matt said:
I'm posting this question for one of my developers who's not quite as
newsgroup-savvy. Any suggestions?

The question follows, along with relevant source code.

-Matt

I have a templated queue class as part of a statically linkable
library (in GQueue.h and .cpp below). The library compiles fine, but
when I go to use it in an executable, I get linker errors complaining
that it can not find references for any of the queue functions. I
compile just the queue class as an object file, and then perform 'nm'
on the queue object and it returns the following:

You can't put template code in a library with contemporary compilers.
Put all the template code in the header files and everything will work
fine. Template code should go in header files.

The reason is that template code is not properly compiled until it is
used (instantiated is the technical term), so there is nothing to go
into the library because the templates haven't been used yet.

Just throw away the .cpp file and put all the code in the .h files.
Distribute the .h files.

John
 
I

Ian

Matt said:
---------------- GQueue.h -----------------
#ifndef GQUEUE_H
#define GQUEUE_H

#include <string>
#include <queue>

using namespace std;
When will people learn not to put this in headers?

Ian
 
B

benben

You can't put template code in a library with contemporary compilers. Put
all the template code in the header files and everything will work fine.
Template code should go in header files.

The reason is that template code is not properly compiled until it is used
(instantiated is the technical term), so there is nothing to go into the
library because the templates haven't been used yet.

Just throw away the .cpp file and put all the code in the .h files.
Distribute the .h files.

John

If you know before hand a set of types to be passes as template arguments,
though, you theoretically can put explicit template instantiations in a
static library. For example:

file: mylib.hpp
--------------------------------

#ifndef HEADER_MYLIB_HPP_INCLUDED
#define HEADER_MYLIB_HPP_INCLUDED

// define the interface:

template <typename T>
class C
{
public:
T clone(void) const;
// ...
};

#endif // inc. guard...

file: mylib.cpp
---------------------------------

#include <mylib.hpp>

// implement the class (template)

template <typename T>
T C<T>::clone(void) const
{
return T();
}

// explicitly instantiate C<> with a bunch
// of built-in types

template class C<int>;
template class C<double>;
template class C<char>;
template class C<bool>;
// ...


Note, however, unless C<T> is explicitly instantiated in mylib.cpp, you will
most likely get linker errors.

Regards,
Ben
 
V

Vijai Kalyan

not ever. It is far more simpler to type that out than qualify
everything with a std:: prefix.

man perl | grep -l virtues

The three principal virtues of a programmer are Laziness, Hubris and
Impatience. See the Camel book for why.

Note "Laziness" :)

-vijai.
 
B

benben

Vijai Kalyan said:
not ever. It is far more simpler to type that out than qualify
everything with a std:: prefix.

man perl | grep -l virtues

The three principal virtues of a programmer are Laziness, Hubris and
Impatience. See the Camel book for why.

Note "Laziness" :)

-vijai.

Not really. I prefer the standard include which gives a nicer list of
auto-completion on my IDE :)

Ben
 
V

Vijai Kalyan

I don't see you using "string" anywhere in your source. If it's not
needed remove it.

-vijai.
 
D

Dave Rahardja

not ever. It is far more simpler to type that out than qualify
everything with a std:: prefix.

It's not nice (especially if you're programming in a team environment) to
pollute the namespace of the module that happens to include your header with
another namespace, even if it is the std namespace.

I use "using namespace xxx" quite often to simplify my modules, however, I
always fully qualify all namespaced entities in my _header_ files.

-dr
 

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
473,744
Messages
2,569,484
Members
44,904
Latest member
HealthyVisionsCBDPrice

Latest Threads

Top