[try Beta version]
Not logged in

 
Linker problems with class template and member function specialization

Jun 16, 2011 at 8:16pm
Hi,
I am new to template programming and the problem I am having, might really be trivial! In any case, I am trying to set up a class template with a specialized function and use it as a base class. Now I have been working on this for a fair amount of time without finding a solution to the compilation error I get.

I divided the class template in two files which are:
>>>> CC.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#ifndef CC_H_
#define CC_H_

#include <iostream>
using namespace std;

template <unsigned int NN>
class CC {
public:
	CC(){};
	virtual ~CC(){};
	void myprint(int);
};

#include "CC.cpp"
#endif /* CC_H_ */
 


>>>> CC.cpp
1
2
3
4
5
6
7
8
9
10
11
12
#ifdef CC_H_

template<unsigned int NN>
void CC<NN>::myprint(int o){
	std::cout << o << " Instance not specialized NN = " << NN << std::endl;
}

template <>
void CC<1>::myprint(int o){
	std::cout <<" Instance specialized to 1 " << std::endl;
}
#endif 

As you can see the class has its member function specialized for the value 1 of NN. The class CC is the base class for the class DD which follows:


>>>> GG.h
1
2
3
4
5
6
7
8
9
10
11
12
#ifndef GG_H_
#define GG_H_
#include "CC.h"

class GG: public CC<1> {
public:
	GG(){CC<1> io; io.myprint(9.0);};
	virtual ~GG(){};
	void My();
};

#endif /* GG_H_ */ 

and the GG.cpp
1
2
3
4
5
6
7
#include "GG.h"
#include <iostream>
using namespace std;

void GG::My(){
	cout << " test " << endl;
}

Finally the main program
1
2
3
4
5
6
7
8
9
#include <iostream>
using namespace std;
#include "GG.h"
#include "CC.h"
int main() {
	GG op;
	op.myprint(90);
	return 0;
}


When compiling I get the following error from the linker


Building target: test
Invoking: GCC C++ Linker
g++  -o"test"  ./src/CC.o ./src/GG.o ./src/test_c.o   
./src/test_c.o: In function `CC<1u>::myprint(int)':
/home/workspace/test/Debug/../src/CC.cpp:15: multiple definition of `CC<1u>::myprint(int)'
./src/GG.o:/home/workspace/test/Debug/../src/CC.cpp:15: first defined here
collect2: ld returned 1 exit status
make: *** [test] Error 1


The error goes away if I change the derived class GG and include CC.h in the main only. What am I doing wrong??

Thanks in advance!!
Max

Jun 17, 2011 at 2:01am
You shouldn't include cpps. It will give you trouble with automagic tools.

I think that the problem resides in that void CC<1>::myprint(int); is not an inline or templatized method, so it shouldn't be defined in a header file.
Jun 17, 2011 at 3:43am
C++ template does not support separating compilation. You should put function implement into header file.

Recommend book: 《C++ template》http://www.amazon.com/Templates-Complete-Guide-David-Vandevoorde/dp/0201734842
Jun 17, 2011 at 8:03am
Actually, I used the inclusion method described in Vandervoorde's book to compile the code in separate files. Also, if I eliminate the inclusion of the .cpp file and copy its content explicitely on the .h file, the code still does not compile.

On the other hand, if I follow ne555 and put the method inline exlicitely, then the code does compile! Still I don't quite understand why. Would you care to elaborate on that? Why one should not (must not??) include non inline, non templatized methods?

Thanks in advance!
Jun 17, 2011 at 4:32pm
The idea wasn't to make it inline but to define it in a source file (as regular method that it is*)
Redefinition http://www.cplusplus.com/forum/beginner/34484/#msg186410

*I'm guessing
Topic archived. No new replies allowed.