Template in cpp file?

B

Bob Altman

Hi all,

I have a project that contains a templated routine. This same project contains
code that tries to construct an instance of that templated routine. I have the
following bits and pieces:

Something.h
// Just the signature, not the implementation
template <class T> void MyTemplatedRoutine(T arg);

MyTemplatedRoutine.cpp
// Implementation
template <class T> void MyTemplatedRoutine(T arg)
{ <implementation> }

X.cpp
// Try to use it
#include "Something.h"
int x = 5;
a = MyTemplatedRoutine(x);

The linker complains that it can't find void __cdecl
MyTemplatedRoutine<int>(int). I need to implement the templated routine in a
code file rather than in the header file because it contains references to
static module-level data declared in the code file. What do I need to do to
make the linker happy?

TIA - Bob
 
M

Mark Salsbery [MVP]

Bob Altman said:
Hi all,

I have a project that contains a templated routine. This same project
contains code that tries to construct an instance of that templated
routine. I have the following bits and pieces:

Something.h
// Just the signature, not the implementation
template <class T> void MyTemplatedRoutine(T arg);

MyTemplatedRoutine.cpp
// Implementation
template <class T> void MyTemplatedRoutine(T arg)
{ <implementation> }

X.cpp
// Try to use it
#include "Something.h"
int x = 5;
a = MyTemplatedRoutine(x);


Your code as shown builds for me fine. I'm suspicious about the assignment
to "a" by a function that returns void...

Mark
 
B

Bob Altman

Your code as shown builds for me fine. I'm suspicious about the assignment to
"a" by a function that returns void...

Whoops... the assignment to "a" is a typo. In any event, if I have all of the
plumbing correct then this should work? I know that exporting templated
functions from a DLL is a pain in the you-know-what, so I thought that maybe I
was running into a variant of that here. But since everything is in the same
project I would expect that C++ is smart enough to wire it all up correctly even
if the template implementation is in a code file and not directly incorporated
in the referencing code via a header file.

I'll stare at my code some more to see if I can figure it out. If I can't then
I'll try to simplify it to something as simple as my original posting and I'll
follow up with a new and improved post in this NG.
 
M

Mark Salsbery [MVP]

Bob Altman said:
Hi all,

I have a project that contains a templated routine. This same project
contains code that tries to construct an instance of that templated
routine. I have the following bits and pieces:

Something.h
// Just the signature, not the implementation
template <class T> void MyTemplatedRoutine(T arg);

MyTemplatedRoutine.cpp
// Implementation
template <class T> void MyTemplatedRoutine(T arg)
{ <implementation> }

X.cpp


Argh - I just noticed the 3rd x,cpp file. That won't work since at that
point, there's not enough info to create an implemented instance of the
template<int> function.

Mark
 
B

Ben Voigt [C++ MVP]

Bob said:
Hi all,

I have a project that contains a templated routine. This same
project contains code that tries to construct an instance of that
templated routine. I have the following bits and pieces:

Something.h
// Just the signature, not the implementation
template <class T> void MyTemplatedRoutine(T arg);

MyTemplatedRoutine.cpp
// Implementation
template <class T> void MyTemplatedRoutine(T arg)
{ <implementation> }

X.cpp
// Try to use it
#include "Something.h"
int x = 5;
a = MyTemplatedRoutine(x);

The linker complains that it can't find void __cdecl
MyTemplatedRoutine<int>(int). I need to implement the templated
routine in a code file rather than in the header file because it
contains references to static module-level data declared in the code
file. What do I need to do to make the linker happy?

Explicitly instantiate the different versions of the template that you need.

Something like

void MyTemplatedRoutine<int>(int arg);

ought to do the trick, or you might need to take its address as in:

static void forceInstantiation()
{
{ void (*force)(int) = &MyTemplatedRoutine<int>; }
{ void (*force)(double) = &MyTemplatedRoutine<double>; }
// won't this be prettier with C++0x and type inference!
...
}
 

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

Top