Skip to main content
GameDev.net gamedev.net
🔒 Locked

Simple thing not compiling

Started by Si_con Jul 24, 2011 at 3:24 PM 5 replies 1.7k views
Original Post
Si_con
Si_con
Hi, i am trying to compile this but i cant, and i dont see the mistake, i get linker error of function func in VS2010, and in code blocks i get "undefined reference". Only works if i put the definition inline in the class, or in the header, but anything i put in cpp file i get the same errors.



File: A.h

#ifndef _A_H_
#define _A_H_

template <class T> class A
{
public:

int n;
A() {};
~A() {};

T func(T n);
};

#endif





File: A.cpp

#include "A.h"

template <class T> T A<T>::func(T n)
{
this->n = n;
return this->n;
}








File: main.cpp

#include <iostream>
#include "A.h"

int main()
{
A<int> a;

std::cout << a.func(2);

return 0;
}


oler1s
oler1s
Templates don't go in cpp files. They aren't very usable if they are not visible, are they now?
Si_con
Si_con
So any class that is templated dont need a .cpp file?
MichaelNett
MichaelNett
Nope,

any template class cannot be defined in (i think it says:) more than one compile unit. That's like the major drawback in C++ templates if you ask me.

Just fit everything into your header file. Btw: you can of course still split the class declaration and the function definitions within the header file.

- Michael.
Si_con
Si_con
Thank you, i thought there were the same as a non templated class, header and cpp files, and then the compiler knew how to manage them to have member functions always visible in the linker stage.
rip-off
rip-off
The answers so far are incomplete.

You can split templates over multiple files. The problem is that if the template implementation isn't available where it is used, it will not be generated. A common solution is to have two header files for templates, the normal header file which declares the template, and a separate file which includes the implementation. The first header also #include<>s the second at the end.

Something like this:

#ifndef A_H
#define A_H

template <class T>
class A
{
public:
int n;
A() {};
~A() {};

T func(T n);
};

#include "a.impl.h"

#endif

And a.impl.h would look like this:

#ifndef A_IMPL_H
#define A_IMPL_H

#include "A.h"

template <class T>
T A<T>::func(T n)
{
this->n = n;
return this->n;
}

#endif

Another option is to use explicit instantiation. With explicit instantiation, you have a normal header file. In the template "source" file, you implement the functions. At the end you provide a set of explicit instantiations, one for each type that will be used.

This is generally used when the number of types used with the template is small.
SiCrane
SiCrane
Well, to be pointlessly pedantic, the current version of the C++ standard does provide a method to put a template definition in a source file: the export keyword. The reason why this is pointless information is that pretty much only one compiler vendor, Comeau, ships a C++ tool chain that can use export - and even then it turns out that it's pretty much just easier to put them in headers.

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.