54

In C++ Primer Plus (2001, Czech Translation) I have found these different template specialization syntax:

function template

template <typename T> void foo(T);

specialization syntax

void foo(int param); // 1
void foo<int>(int param); // 2
template <> void foo<int>(int param); // 3
template <> void foo(int param); // 4
template void foo(int param); // 5

Googling a bit, I have found only No.3 examples. Is there any difference (in call, compiling, usage) among them? Are some of them obsolete/deprecated? Why not just use No.1?

Jan Turoň
  • 26,696
  • 21
  • 102
  • 153
  • 3
    It is a good idea to generally use (and think in ) the term "function template" as this emphasizes that it is a template, not a function, and that wherever a function is needed, you can't use a template (only a specialization, since those are functions then). – PlasmaHH Nov 30 '11 at 09:38
  • It either a bad translation or you just get it wrong. I suggest you to read more about difference between templates and function overloading. – varepsilon Nov 30 '11 at 09:28

2 Answers2

83

Here are comments with each syntax:

void foo(int param); //not a specialization, it is an overload

void foo<int>(int param); //ill-formed

//this form always works
template <> void foo<int>(int param); //explicit specialization

//same as above, but works only if template argument deduction is possible!
template <> void foo(int param); //explicit specialization

//same as above, but works only if template argument deduction is possible!
template void foo(int param); //explicit instantiation

Added by me:

//Notice <int>. This form always works!
template void foo<int>(int param); //explicit instantiation

//Notice <>. works only if template argument deduction is possible!
template void foo<>(int param); //explicit instantiation

From coding point of view, overload is preferred over function-template-specialization.

So, don't specialize function template:

And to know the terminologies:

  • instantiation
  • explicit instantiation
  • specialization
  • explicit specialization

See this :

Community
  • 1
  • 1
Nawaz
  • 327,095
  • 105
  • 629
  • 812
  • 4
    +1, with a note that the overload should probably be preferred. – avakar Nov 30 '11 at 09:24
  • @avakar: with the link to the related [GotW `Why Not Specialize Function Templates?`](http://www.gotw.ca/publications/mill17.htm) article by Herb Sutter – sehe Nov 30 '11 at 09:26
  • 1
    The explicit instantiation should be `template void foo(int param)`, or `template void foo<>(int param)` when the template parameter is deduced. – fefe Nov 30 '11 at 09:28
  • @fefe: Yes. right. Overlooked that. Edited my answer anyway. Thanks. – Nawaz Nov 30 '11 at 09:31
  • 1
    Your second last is not correct. that is a valid explicit specialization. doesnt need<> – Johannes Schaub - litb Nov 30 '11 at 09:32
  • @JohannesSchaub-litb: So we can write both? – Nawaz Nov 30 '11 at 09:34
  • @JohannesSchaub-litb: Alright. Just verified it. Edited my answer. – Nawaz Nov 30 '11 at 09:35
  • Just found this in the specification : `If the explicit instantiation is for a function or member function, the unqualifiedid in the declaration shall be either a template-id or, where all template arguments can be deduced, a template-name or operator-function-id`. This means the fifth is allowed? – fefe Nov 30 '11 at 09:37
  • @fefe: Yes. There is even an example in §14.7.2/2 (C++03) – Nawaz Nov 30 '11 at 09:38
  • "_explicit instantiation, not specialization_" explicit instantiations are also called "specialisation" – curiousguy Nov 30 '11 at 09:44
  • The fourth is also good according to §14.7.3/11 (C++03) {§14.7.3/10 (C++0x)} `A trailing template-argument can be left unspecified in the template-id naming an explicit function template specialization provided it can be deduced from the function argument type.` and an example is given. – fefe Nov 30 '11 at 09:55
  • I already said the 4th is ok but he didnt change it yet. btw."foo" is not a template-id. your quote is inappropriate – Johannes Schaub - litb Nov 30 '11 at 09:58
  • @fefe: Nice one. I saw an example in the spec as well. – Nawaz Nov 30 '11 at 10:00
  • @JohannesSchaub-litb seems that the spec treated it as a `trailing template-argument ... left unspecified in the template-id`, and the example also belong to this. I cannot find anything related elsewhere. – fefe Nov 30 '11 at 10:39
  • @fefe it's at 14.8.1p3 . Not at the subclause about explicit specialization, but at the subclause about referring to specializations in general, which applies equally. The example you referred to does not properly reflect the normative text you quoted; perhaps even the whole text you quoted is redundant, faced with 14.8.1p3. – Johannes Schaub - litb Nov 30 '11 at 11:43
  • @JohannesSchaub-litb: I've corrected that too. Let me know if there is any error in my answer. – Nawaz Dec 01 '11 at 06:26
  • @Nik-Lz: I dont know what scenario you're talking about. But [it works for me and it must work for all, else report a bug for the compiler you're using](http://coliru.stacked-crooked.com/a/f10e7317522c4971). – Nawaz Jul 18 '18 at 10:37
  • @Nik-Lz: Is it possible to post the *exact* code you have written? You can remove the function body, just the declaration of the primary template, explicit instantiation and how you call it. 3 things, that is it! – Nawaz Jul 18 '18 at 12:17
  • @Nik-Lz: Lots of information are missing. And whatever is shown, doesn't seem to be correct, or you're doing entirely different thing. Also, I dont see any *explicit instantiation* there. Could you please post the primary template? – Nawaz Jul 18 '18 at 12:30
  • @Nik-Lz: Note that the order of declaration of your primary template and explicit instantiation/specialization matters! – Nawaz Jul 18 '18 at 12:52
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/176252/discussion-between-nawaz-and-nik-lz). – Nawaz Jul 18 '18 at 13:25
1

Using Visual Studio 2012, it seems to work slightly different if there's no function argument:

template <typename T> T bar( );
//template int bar<int>( ) { return 0; } doesn't work
template < > int bar<int>( ) { return 0; } //does work
gerardw
  • 4,437
  • 33
  • 33