23
##A.hh

template<class T> void func(T t) {}
template<> void func<int>(int t) {}

void func2();

##A.cpp

void func2() {}

##main.cpp

func("hello");
func(int());

The error I get is: error LNK2005: "void __cdecl func(int)" (??$func@H@@YAXH@Z) already defined in A.obj, one or more multiply defined symbols found

Is a function template specialization not treated as a normal function template? It looks like it will be in the objective file for A.

templatetypedef
  • 362,284
  • 104
  • 897
  • 1,065
hidayat
  • 9,493
  • 13
  • 51
  • 66

2 Answers2

39

As template<> void func<int>(int t) {} is a function overload rather than a function template (i.e., all types are known at the point of definition so it is no longer a template), it must be marked as inline or defined in a .cpp file to avoid multiple definition errors, just as with any other function definition.

ildjarn
  • 62,044
  • 9
  • 127
  • 211
  • 1
    But if its treated as a normal function, what is then the difference with an overloaded function: inline void func(int t) {} – hidayat Mar 24 '11 at 10:04
  • 4
    @hidayat : Overload resolution precedence is the only difference -- non-templates are always preferred over templates (see 13.3.3). This is covered in detail in the book 'More Exceptional C++' by Herb Sutter. – ildjarn Mar 24 '11 at 10:08
15

The problem is as follows: full template specialization is no more a template, it's more like an ordinary function. So you should act accordingly:

  • either put definition of func<int>() in cpp file

  • or make it inline

Alexander Poluektov
  • 7,844
  • 1
  • 28
  • 32