2

I have to use an external library, but am getting a "multiple definition error" from following template function and its explicit specialization, if it gets called with a std::string.

template <typename T>
void foo(T& value);

template <>
void foo(std::string& value);

even if I change the 2nd function to

void foo(std::string& value);

the problem is the same.

According to [1] at least the version without a template (the "plain old function") should be prefered over the template version.

Does anybody have a clue, where the problem could be?

[1] http://www.gotw.ca/publications/mill17.htm

randooom
  • 541
  • 2
  • 11
  • The error is when compiling or when linking? Also, maybe the header file is not well guarded by macros to be included only once. – Diego Sevilla Sep 20 '10 at 19:51
  • Do you only have the function definitions in your header file? You need the entire body. See here: http://www.parashift.com/c++-faq/templates.html#faq-35.12 – Matt K Sep 20 '10 at 19:58
  • Thanks guys, GMan's answer did the trick. – randooom Sep 20 '10 at 20:06

1 Answers1

3

You're breaking the one-definition rule.

Unless a function is inline, it can only be defined once. If you mark the function as inline, so long as the definitions match they can be defined as often as desired. Template functions behave as if they were implicitly inline, so you don't get errors with templates.

However, an explicit specialization or non-template function is not implicitly inline and because you're including it in multiple translation units, you get multiple definitions; this breaks the rule. You should mark it as inline:

template <>
inline void foo(std::string& value);

(If you're getting this before link time, you need include guards.)

GManNickG
  • 494,350
  • 52
  • 494
  • 543
  • Just noting for future reference: $14.7.3/14 - "An explicit specialization of a function template is inline only if it is explicitly declared to be, and independently of whether its function template is." Would you please tell us the reference about 'template functions are implicitly inline'? – Chubsdad Sep 21 '10 at 02:20
  • Do you also want to change 'template function' to 'function template', and 'specialization to explicit specialization' in your response? Have already +1'ed – Chubsdad Sep 21 '10 at 02:23
  • 8.1.2 of "C++ Templates" (http://www.amazon.com/Templates-Complete-Guide-David-Vandevoorde/dp/0201734842), mentions "Templates usually have external linkage. The only exceptions are namespace scope function templates with the static specifier: – Chubsdad Sep 21 '10 at 02:50
  • @Chubsdad: I spoke too loose. They aren't `inline`, they simply behavior *similarly* (the compiler and/or linker needs to be smart enough to act as if it only instantiates it once). – GManNickG Sep 21 '10 at 05:27