145

I have a template function with one argument. I have to instantiate that function without calling that function means explicitly I have to instantiate.

I have this function:

template <class T> int function_name(T a) {}

I instantiated that function like this:

template int function_name<int>(int);

But I got the following errors:

error: expected primary-expression before 'template'
error: expected `;' before 'template'
Vertexwahn
  • 7,709
  • 6
  • 64
  • 90
Balaji
  • 1,459
  • 2
  • 11
  • 4

3 Answers3

219

[EDIT 2]: Note that there was some confusion regarding the code in the original question due to code formatting issues. See AnthonyHatchkins' answer for more details.

If you really want to instantiate (instead of specialize or something) the function, do this:

template <typename T> void func(T param) {} // definition

template void func<int>(int param); // explicit instantiation.

[EDIT] There seems to be (a lot) of confusion regarding explicit instantiation and specialization. The code I posted above deals with explicit instantiation. The syntax for specialization is different. Here is syntax for specialization:

template <typename T> void func(T param) {} // definition

template <> void func<int>(int param) {} // specialization

Note that angle brackets after template!

hrnt
  • 9,882
  • 2
  • 31
  • 38
  • 4
    that is *instantiation* or *specialization*? – Nawaz Feb 08 '11 at 12:50
  • @hrnt : Compiler *"instantiates"* templates, programmers only *"specializes"* it. Instantiation is an act of creating a specialization out of templates by the compilers! – Nawaz Feb 08 '11 at 12:53
  • 8
    Not true. You can tell the compiler to explicitly instantiate templates. Google for "C++ explicit template instantiation" for more details. – hrnt Feb 08 '11 at 12:56
  • 9
    @Nawaz: you are wrong. Of course it is always the compiler the one that instantiates, that line is a request from the programmer to the compiler to instantiate the template. If you have a copy of the C++ standard, read **14.7.2 Explicit instantiation** – David Rodríguez - dribeas Feb 08 '11 at 12:58
  • 1
    @hrnt: explicit instantiation is when programmers explicitly mentions the types *when calling the function*. – Nawaz Feb 08 '11 at 12:59
  • 19
    Specialization means you are probably changing its implementation. Instantiation simply means you are assigning it to a particular compilation unit, possibly to take its unique address or make it available as a library function or to reduce bloat. – CashCow Feb 08 '11 at 13:03
  • @David: You yourself said it *" that line is a request from the programmer to the compiler to instantiate the template"*. Exactly, it's a request. But the actual instantiation is done by the compilers, when you CALL it in your code. If you don't call, there is no *instantiation* , there is only *specialization*. – Nawaz Feb 08 '11 at 13:03
  • 3
    @Nawaz: Not true. You don't need to call the function - just the explicit instantiation is enough. See for yourself - explicitly instantiate a function and see the generated object file. – hrnt Feb 08 '11 at 13:07
  • @hrnt I think asker wants to insert function code to compilation unit without calling it. You are suggesting, to specialize it, arguing, that it is also calling explicit instantiation. – UmmaGumma Feb 08 '11 at 13:07
  • @Ashot: No, I am not suggesting to specialize it. The code I posted has nothing to do with specialization. – hrnt Feb 08 '11 at 13:08
  • 3
    @hrnt: I think, you're right. @Ashot : I just noticed that the syntax doesn't has `template<>` form. What he has written is different from *specialization*. +1 for teaching me this new thing. I'm removing my post. :D – Nawaz Feb 08 '11 at 13:11
  • @hrnt have you try to call func after code you write?? You will get error (undefined reference to func ) – UmmaGumma Feb 08 '11 at 13:12
  • @Ashot: Yes I have, and yes it works. I edited my answer to clarify the syntax difference between _specialization_ and _explicit instantiation_. The difference is subtle :) – hrnt Feb 08 '11 at 13:14
  • 1
    @hrnt: Yes, that difference is subtle, and all source of confusion. Good post, especially the edit, by the way. :-) – Nawaz Feb 08 '11 at 13:16
  • 1
    @hrnt, indeed +1 from me too, picked up something new today... awesome. – Nim Feb 08 '11 at 13:28
  • 1
    @hrnt: may be a worthwhile addition to also include an example for "deduced template argument" in the explicit instantiation part, e.g.: template void func(int param); // explicit instantiation with deduced template argument – Ákos Nov 21 '13 at 12:13
  • @AntonyHatchkins That is because somebody edited the original question after I answered it :P See the edit history, the original piece of code didn't look like that. – hrnt Jan 08 '14 at 13:54
  • If _you_ looked into edit history you would see that Bill didn't add anything into the code, just formatting. Those brackets were in place from the beginning. It's just SO frontend which didn't display them as OP intended. – Antony Hatchkins Jan 08 '14 at 17:43
  • For other readers and myself in future, to avoid code duplication of long function signature : see https://stackoverflow.com/questions/22628943/how-do-i-force-a-specific-instantiation-of-a-templated-function-without-repeatin , https://stackoverflow.com/questions/28355934/can-i-use-decltype-or-something-similar-for-explicit-template-instantiation-wi?rq=1 – cppBeginner Sep 21 '20 at 09:13
22

Your code is correct.

The error message pertains to a place in the code that you didn't quote here.

Update:

Original code was

template <class T> int function_name(T a) {}
template int function_name<int>(int);

and it was correct.

But it was not quoted and thus looked like this:

template int function_name(T a) {}
template int function_name(int);

It generates the following error

a.cpp:1: error: explicit instantiation of non-template ‘int function_name’
a.cpp:1: error: expected `;' before ‘(’ token
a.cpp:3: error: ‘function_name’ is not a template function

which is clearly different from what OP cited.

In this variant the second line is ok (<int> can be omitted here), but the first line is faulty. The compiler cannot guess that T is a template parameter.

Antony Hatchkins
  • 31,947
  • 10
  • 111
  • 111
  • Technically it was not his code, it was Bill's edit :) The original code is `template int function_name( T a) { }` and `template int function_name(int);` – hrnt Jan 08 '14 at 13:59
  • @hrnt Original code was not formatted correctly, yet it was correct. If I were __Balaji__ I would return and accept your answer if he considers it useful, yet for me (and presumably for anyone else) your answer (while being perfectly right by itself) doesn't answer the question. – Antony Hatchkins Jan 08 '14 at 17:47
  • @hrnt You're right that the original code looked like that. But because of deduced template argument it still works. I have to agree with Antony Hatchkins that the error arises from code that the OP didn't quote, however I think your answer is still useful for people who didn't know about explicit instantiation. – mpark Jan 08 '14 at 18:25
  • Well, take me for example. I googled this page when I wanted to refresh my well-forgotten knowledge about explicit instantiation - and it didn't help me much. As for me, there is no confusion about the syntax. What may cause confusion about the explicit instantiation is its usage – Antony Hatchkins Jan 09 '14 at 04:59
  • @AntonyHatchkins Ah, true - I didn't look at the source of the original question, just how it appeared on my screen. I'll +1 this and amend my original answer to note the confusion regarding the original question. – hrnt Jan 09 '14 at 09:30
9

This may be helpful for instantiation template method when we want to split cpp/hpp file.

// foo.hpp

struct Foo
{
    template<typename T>
    void myMethod(T var);
};

// foo.cpp
#include <typeinfo>
#include <iostream>

template void Foo::myMethod(int var);

template void Foo::myMethod(double var);

template <typename T>
void Foo::myMethod(T var)
{
    std::cout << typeid(T).name() << " - " << var << std::endl;
}

Example:

    Foo foo;
    foo.myMethod(1);
    foo.myMethod(2.0);
    
    // undefined reference to `void Foo::myMethod(float)'
    // foo.myMethod(2.0F); <-- doesn't work as we don't have definition
OUT:
i - 1
d - 2

You can play it here: https://onlinegdb.com/gwAjMF9QH

Gelldur
  • 11,187
  • 7
  • 57
  • 68