Use of template function instantiation

A

Alex Vinokur

When is it necessary to use template function instantiation?

template<typename T> void foo(T) { }

template void foo<int> (int); // Instantiation with the explicitly
specified template.

template void foo(char); // Instantiation with the deduced
template argument 'char'.

template void foo(double d) // Specialization
{
// Specialization
}

int main()
{
foo(123); // int
foo ('a'); // char
foo (3.14); // double - specialization
foo (std::string());
return 0;
}

What is the difference here between calling foo(123), foo (3.14), foo
(std::string()) ?

Thanks,

Alex .
 
F

feverzsj

Alex said:
When is it necessary to use template function instantiation?

You mean explicit instantiation?
The case one using explicit instantiation is when compiler takes too
long time to instantiate the template in place for many times.
To achieve this, you have to manage the source code carefully, which
I think is not worth the candle.
Here contains some examples, http://www.codeproject.com/KB/cpp/templatesourceorg.aspx
template<typename T> void foo(T) { }

template void foo<int> (int);  //  Instantiation with the explicitly
specified template.

template void foo(char);             // Instantiation with the deduced
template argument 'char'.

template void foo(double d)   // Specialization
{
  // Specialization

}

int main()
{
   foo(123);   // int
   foo ('a');     // char
   foo (3.14);   // double - specialization
   foo (std::string());
   return 0;

}

What is the difference here between calling foo(123), foo (3.14), foo
(std::string()) ?

Calling different instantiations, but your usage of explicit
instantiation is useless. Still check the web page above.
 
J

Jorgen Grahn

You mean explicit instantiation?
The case one using explicit instantiation is when compiler takes too
long time to instantiate the template in place for many times.

I've only used explicit instantiation once, and it was not the case
you describe above (which you think is the *only* case, right?).

My case was simple: I started out with a class

class Foo {
...
void bar(const A&);
void bar(const B&);
void bar(const C&);
};

with the three Foo::bar() very similar, and A, B, C with similar
interfaces but not related by inheritance (I dislike using inheritance
in cases where I don't need run-time polymorphism).

So that turned into:

class Foo {
...
template<class T> void bar(const T&);
};

with the template member defined in the implementation file, followed
by explicit instantiations for A, B and C. I expect I'll be adding a
D, E and F later.

Is this a common idiom, by the way? I "discovered" it by accident; I
don't have that much experience with templates.

/Jorgen
 
D

Daniel Pitts

Jorgen said:
I've only used explicit instantiation once, and it was not the case
you describe above (which you think is the *only* case, right?).

My case was simple: I started out with a class

class Foo {
...
void bar(const A&);
void bar(const B&);
void bar(const C&);
};

with the three Foo::bar() very similar, and A, B, C with similar
interfaces but not related by inheritance (I dislike using inheritance
in cases where I don't need run-time polymorphism).

So that turned into:

class Foo {
...
template<class T> void bar(const T&);
};

with the template member defined in the implementation file, followed
by explicit instantiations for A, B and C. I expect I'll be adding a
D, E and F later.
That is an interesting trick. Although I think I would hide that as an
implementation detail, keeping the template logic to Foo.cc, rather
than Foo.h
--- foo.h ---
class Foo {
...
void bar(const A&);
void bar(const B&);
void bar(const C&);
};

--- foo.cc ---

#include "foo.h"

template<typename T>
void handleBar(const T&t) {
// bar logic
}

void Foo::bar(const A&a) { handleBar(a); }
void Foo::bar(const B&b) { handleBar(b); }
void Foo::bar(const C&c) { handleBar(c); }

--- ---
 
J

Jorgen Grahn

That is an interesting trick.

I thought so too, but maybe it just looks interesting and "tricky"
because there's so much focus on templates as a way to provide
infinite flexibility. Here I just used it to avoid copy&paste.
Although I think I would hide that as an
implementation detail, keeping the template logic to Foo.cc, rather
than Foo.h
--- foo.h ---
class Foo {
...
void bar(const A&);
void bar(const B&);
void bar(const C&);
};

--- foo.cc ---

#include "foo.h"

template<typename T>
void handleBar(const T&t) {
// bar logic
}

void Foo::bar(const A&a) { handleBar(a); }
void Foo::bar(const B&b) { handleBar(b); }
void Foo::bar(const C&c) { handleBar(c); }

--- ---

That's even nicer. It doesn't matter *that* much in my real-life case.
Unlike in the A/B/C example it's fairly obvious which types can be
arguments to Foo::bar() -- they are all alone in a namespace and
correspond to requests in a networking protocol.

/Jorgen
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,011
Latest member
AjaUqq1950

Latest Threads

Top