# MS Visual Studio C++ problem

1. Apr 27, 2012

### AlephZero

This little test of templates and non-member functions works fine:

Code (Text):

// test5.cpp : main project file.

#include "stdafx.h"

using namespace System;

template <class T> void mytest(void);

int main(array<System::String ^> ^args)
{
mytest<double>();
mytest<int>();
return 0;
}

template <class T> void mytest (void)
{
T x = 1;
T y = 2;
Console::WriteLine("size of T = {0} x/y = {1}",sizeof(T),x/y);
}

I want to split this up so function mytest is in its own .cpp file, but I can't get it to work.

It compiles OK but I get
Code (Text):

test5.obj : error LNK2028: unresolved token (0A000006) "void __cdecl mytest<int>(void)" (??$mytest@H@@$$FYAXXZ) referenced in function "int __clrcall main(cli::array<class System::String ^ >^)" (?main@@$$HYMHP$01AP$AAVString@System@@@Z) test5.obj : error LNK2028: unresolved token (0A000007) "void __cdecl mytest<double>(void)" (??$mytest@N@@$$FYAXXZ) referenced in function "int __clrcall main(cli::array<class System::String ^ >^)" (?main@@$$HYMHP$01AP$AAVString@System@@@Z)
test5.obj : error LNK2019: unresolved external symbol "void __cdecl mytest<int>(void)" (??$mytest@H@@$$FYAXXZ) referenced in function "int __clrcall main(cli::array<class System::String ^ >^)" (?main@@$$HYMHP$01AP$AAVString@System@@@Z) test5.obj : error LNK2019: unresolved external symbol "void __cdecl mytest<double>(void)" (??$mytest@N@@$$FYAXXZ) referenced in function "int __clrcall main(cli::array<class System::String ^ >^)" (?main@@$$HYMHP$01AP$AAVString@System@@@Z)

which suggests it doesn't realize it has to instantiate the templates.

What am I doing wrong? FWIW changing "class T" to "typename T" makes no difference.

2. Apr 27, 2012

### D H

Staff Emeritus
You don't forward declare template functions. It doesn't make sense. Put the template definition above your main and all should be fine.

3. Apr 27, 2012

### Staff: Mentor

I guess you have (two) different cpp files, each containing part of the code? Are both parts of the same project? Perhaps linker has no idea where to look for the compiled code.

4. Apr 27, 2012

### I like Serena

Usually you are forced to put the entire template function (including body) in a header file.
This is necessary since the expansion into code only takes place when it's actually used.
Just like an old style C macro.

5. Apr 27, 2012

### AlephZero

Yes the two files are part of the same project.

Yes ... (as with DH's reply) ... except this will finish up as a big library of non-class functions, and the idea of including maybe 106 lines of code in header file(s) doesn't seem the right way to go, and neither does creating an intricate logical structure to dissect it into smaller pieces.

Actually, I've stumbled across a reasonably good solution in the MS documentation. You can explicitly instantiate a template function like this:

Code (Text):

// file mytest.cpp

template <class T> void mytest (void);

template void mytest <int> (void);
template void mytest <double> (void);

template <class T> void mytest (void)
{
T x = 1;
T y = 2;
Console::WriteLine("size of T = {0} x/y = {1}",sizeof(T),x/y);
}

And then call them in another file.

That will probably work OK for me, because most of the time I know in advance what classes I want to instantiate, and it will keep the function definitions out of the header files.

Thanks all.

Last edited: Apr 27, 2012
6. Apr 27, 2012

### D H

Staff Emeritus
What makes you think you will get 106 lines of code in header files? I think this is a case of premature optimization. "Premature optimization is the root of all evil (or at least most of it) in programming." (Donald Knuth). Don't worry about problems that don't exist.

The standard approach with templates is to put them into headers. When you do that, you typically declare your free function templates as inline.

7. Apr 27, 2012

### AlephZero

It's a code porting (and language conversion) project, so I know where I'm starting from. And as with most "computer archeology" type projects, that isn't the place one would want to start from given a free choice...