Simple thing not compiling

Started by
5 comments, last by SiCrane 12 years, 8 months ago
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;
}


Advertisement
Templates don't go in cpp files. They aren't very usable if they are not visible, are they now?
So any class that is templated dont need a .cpp file?
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.
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.
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.
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.

This topic is closed to new replies.

Advertisement