Why does the following code not work when compiling with:
$ g++ temp_main.cpp temp_spec.cpp /tmp/ccirjc3Y.o:temp_spec.cpp:(.text+0x100): multiple definition of `my::say()' /tmp/ccSo7IVO.o:temp_main.cpp:(.text$_ZN2myILi0EE3sayEv[my::say()]+0x0): first defined here collect2: ld returned 1 exit status
I’m trying to have specialization of static function only when using
paramteter 0.
temp_gen.h:
#ifndef temp_gen_h
#define temp_gen_h
#include <iostream>
template<int N>
struct my
{
static void say();
};
template<int N>
void my<N>::say()
{
std::cout << "generic " << N << std::endl;
}
#endif
temp_spec.h:
#ifndef temp_spec_h
#define temp_spec_h
#include <iostream>
#include "temp_gen.h"
template<>
void my<0>::say()
{
std::cout << "specialized " << 0 << std::endl;
}
#endif
temp_spec.cpp:
#include "temp_spec.h"
temp_main.cpp:
#include "temp_gen.h"
int main(int argc, char* argv[])
{
my<0>::say(); //should say "specialized 0"
my<1>::say(); //should say "generic 0"
}
From within your
main.cpp, you did not specialize the template class, this is because you don’t include thetemp_spec.h.As Vaughn Cato pointed out (see comments), you should move the definition of the specialized method (which is no template method anymore), to
temp_spec.cpp.I think (but I’m not an expert at this) you should always put specialization directly below the generic template (in the same header file), because whenever you include this, you also want the specialized ones to be defined, otherwise you will be confused when such errors happen. You can, however, just include the
temp_spec.hat the bottom oftemp_gen.h.Also, you don’t need the .cpp files for the template headers, as there will never be any code to be compiled separately (template classes are always compiled at the other .cpp file which uses it, and I think duplicates will be removed when linking, causing trouble at link time again when in one case you did not specialize it, one time you did)[This paragraph only applies to the generic template class, not to (fully) specialized classes, as they require some code in their own compilation unit, see comments and the edit above.]