Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Template specialization for static function when compiling with g++

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"
}
like image 211
omittones Avatar asked Jul 14 '26 16:07

omittones


1 Answers

From within your main.cpp, you did not specialize the template class, this is because you don't include the temp_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.h at the bottom of temp_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.]

like image 126
leemes Avatar answered Jul 16 '26 05:07

leemes