77

Suppose I've declared:

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

Now, what is the difference between

template <> void foo<int>(int& t);

and

template void foo<int>(int& t);

semantically? And do template-with-no-brackets and template-with-empty-brackets have other semantics in other contexts?


Related to: How do I force a particular instance of a C++ template to instantiate?

Community
  • 1
  • 1
einpoklum
  • 86,754
  • 39
  • 223
  • 453

2 Answers2

71

template <> void foo<int>(int& t); declares a specialization of the template, with potentially different body.

template void foo<int>(int& t); causes an explicit instantiation of the template, but doesn't introduce a specialization. It just forces the instantiation of the template for a specific type.

einpoklum
  • 86,754
  • 39
  • 223
  • 453
Mark B
  • 91,641
  • 10
  • 102
  • 179
  • 3
    That is quite confusing! I assume the meaning of the declaration is that the compiler will not accept the instantiation of the unspecialized template as a candidate, when the specialized definition is not found? – einpoklum Feb 05 '15 at 22:00
  • 3
    Explaining this a bit more: the first one can be used in a header file and it says "`foo` will have a different body to `foo`" ; if code elsewhere in the program calls `foo()` but you don't provide the body then you should get alink error. – M.M Feb 05 '15 at 22:34
  • 4
    The second one should not be used in a header file; using it in one .cpp file makes sure that the body of `foo` (which uses the `foo` template to generate it unless you also had the specialization line!) is actually processed (It's somewhat like *defining* a non-template function) . Normally you don't need to do this as it happens whenever some other code calls `foo` , but you might want to do it [for a few reasons](http://stackoverflow.com/questions/2351148/explicit-instantiation-when-is-it-used) – M.M Feb 05 '15 at 22:36
  • It's less confusing if you see the <> as a special case of an empty template parameter list. In general, you use this syntax to create (**possibly partial**) specializations. If it happens to not have any parameters (that is, not partial) it gives you that syntax. You are still declaring *a template*. – JDługosz Feb 06 '15 at 08:05
  • @jdlugosz: I was under the impression that partial specialization is not supoorted... – einpoklum Feb 06 '15 at 08:42
13

With class/struct,

template <typename T> struct foo {};

Following is a specialization:

template <> struct foo<int>{};

Following is an explicit instantiation:

template struct foo<int>;
Jarod42
  • 173,454
  • 13
  • 146
  • 250