Template Specialization - Please explain explicit instantiation

This is a discussion on Template Specialization - Please explain explicit instantiation within the C++ Programming forums, part of the General Programming Boards category; I'm learning C++ via C++ Primer Plus, Fifth Edition and I'm having trouble understanding the differences between implicit instantiation and ...

Template Specialization - Please explain explicit instantiation

This type of instantiation is termed implicit instantiation because the compiler deduces the necessity for making the definition by nothing that the program uses a Swap() function with int parameters.

Originally, using implicit instantiation was the only way the compiler generated function definitions from templates, but now C++ allows for explicit instantiation. That means you can instruct the compiler to create a particular instantiation--for example, Swap<int>()--directly.

This sentence in particular is confusing:

That means you can instruct the compiler to create a particular instantiation

What is the advantage of this?

Can anyone explain this or provide urls to a thorough explanation and more importantly, why one is more important than the other?

I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.

Unfortunately I did not feel that those FAQ entries explained the question. I checked there and other places before posting here. I guess the benefit between explicit instantiation and implicit instantiation is a little more obvious to regular C++ users, but I haven't figured it out yet. I'll keep reading and hope it becomes obvious later on.

This book is taking a different approach and teaching templates before classes and object (which is in a different order than other books I've seen recently) so perhaps when I get to objects/classes it will make more sense.

Oh dear, I read your original post again, and it looks like I grossly misread it.

Taking the example given in your book, suppose we have a function template that performs a generic swap:

Code:

template <typename T>
void swap(T& x, T& y)
{
T t(x);
x = y;
y = t;
}

We could use this to swap two ints:

Code:

int a = 1, b = 2;
swap(a, b);

The compiler looks at the arguments passed and deduces that T in the template must be int. However, we could also specify this explicitly:

Code:

int a = 1, b = 2;
swap<int>(a, b);

Now, regardless of the argument types, the compiler instantiates swap with T as int.

As for advantages: I would think that most of the time, you want to use implicit specialisation. If an ordinary function of the same signature exists, the compiler will choose that one, and it is more likely to be the "most optimised" version compared to the function template. Perhaps one benefit of explicitly providing template arguments is that you can be sure of what types are being used at that point, but I cannot think of a good example of that right now. There is a rather lame example though:

In the first example, we get integer division. In the second, despite the arguments being ints, we get floating point division.

EDIT:
Decided to check my terminology, and looks like I got it wrong. Templates are a tricky business

Anyway, here's the deal: template specialisation occurs when you provide the template with arguments. So, swap(a, b) implicitly specialises swap() with the type of a and b, which in my example was int. divide<double> explicitly specialises divide with double. In both cases, there was also template instantiation, as the compiler had to work out the implementation of the function from the template. The FAQ I linked to talks about explicit specialisation that refines the implementation. In such a case, if you happen to specialise the same function template (which is no longer really a template as its template parameters are all specified), no template instantiation occurs.

Last edited by laserlight; 08-11-2007 at 02:37 PM.
Reason: Corrections for template terminology.

I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.

explicit instantiation is basically for when it isn't possible for the compiler to work out the template parameters implicitly. For example, it may be that none of the function parameters depend on the templated types. Perhaps the returns value is all that depends on the templated types, or perhaps it is only the inner workings of the function.

Unfortunately I did not feel that those FAQ entries explained the question. I checked there and other places before posting here. I guess the benefit between explicit instantiation and implicit instantiation is a little more obvious to regular C++ users, but I haven't figured it out yet. I'll keep reading and hope it becomes obvious later on.

When possible, implicit instantiation is preferred (When template parameter deduction can be used), because having to specify a type when using a template is a bit of a pain.

Sometimes, templates can't deduce the type automatically, because there's no parameter(s) to deduce the type(s) from, so there's no choice but to use explicit instantation - this is the case with much of the STL, for example

Code:

std::vector<int> my_int_vector;

There's no way that the STL vector template could deduce that my_int_vector was going to be a vector<int> without the int parameter between the angle-brackets. This is where explicit instantiation is mandatory in order for the complete vector type to be created.

Sometimes, templates can't deduce the type automatically, because there's no parameter(s) to deduce the type(s) from, so there's no choice but to use explicit instantation - this is the case with much of the STL, for example

Code:

std::vector<int> my_int_vector;

There's no way that the STL vector template could deduce that my_int_vector was going to be a vector<int> without the int parameter between the angle-brackets. This is where explicit instantiation is mandatory in order for the complete vector type to be created.

I don't think that's a very good example. Explicit/implicit instantiation applies ONLY to function templates. Class templates are NEVER implicitly instantiated.