TITLE: Example usage of template specialization

PROBLEM: papanik@supercrypt.cs.uni-sb.de (Thomas Papanikolaou)

PROBLEM
=======

Suppose you have some template class and some efficient algorithms
for special types. For example:

template <class T> class Gcd {

	T gcd;

	public:

	constructors;
	destructor;

	void gcd(int, int);
	void gcd(double, double);
	void gcd(T, T);
};

main() {

	Gcd <double> d.gcd(2.0, 4.0);
}

How can you achieve that the compiler chooses at compile-time the algorithm
one specifies for a type (or if none such exist the generic algorithm)?


RESPONSE: clamage@taumet.Eng.Sun.COM (Steve Clamage), 13 Jun 94

Write the declaration for the template function, then provide
specializations for the types of interest. As you noted, the above
will not compile, since you wind up with two versions of gcd(int,int)
when you instantiate Gcd<int>, and similarly for double.

Compilers differ in the exact way they want to see the code, but try this:

#include <stdio.h>

template <class T> class Gcd {
public:
	Gcd();
	void gcd(T, T);	// just one decl
};

// just one version of the constructor in this example
template<class T> Gcd<T>::Gcd() { puts("called GCD ctor"); }

// generic template version of gcd function
template<class T> void Gcd<T>::gcd(T, T) { puts("called gcd(T, T)"); }

// specialized versions of gcd for int and double
void Gcd<double>::gcd(double, double) { puts("called gcd(double, double)"); }
void Gcd< int  >::gcd(int,    int   ) { puts("called gcd(int, int)"); }

// dummy class which should force a template instantiation
class A { int i; };

main()
{
    Gcd<double> d;	// should use double specialization
    d.gcd(2.0, 4.0);

    Gcd<int> i;		// should use int specialization
    i.gcd(2, 4);

    Gcd<A> a;		// should generate a template version for A
    a.gcd(A(), A());

    return 0;
}

One problem is that you can't pass some types by value and others by
const reference. If you want some types, like BigNum or Tensor, to be
passed by reference, use reference-to-const parameter types, and accept
a little extra overhead for simple types.
