Webocreation

Monday, November 23, 2009

Template Libraries

Template Libraries
Visual C++ provides two libraries of templates: the Active Template Library (ATL) and the Standard Template Library (STL).

Template libraries such as ATL and STL differ from traditional C++ class libraries in that they are typically supplied only as source code (or as source code with a small supporting run-time library) and are not inherently hierarchical in structure. Rather than deriving from a class to get the functionality you want, you instantiate a class from a template.

Active Template Library

The Active Template Library is a set of templates with which you can easily create small, fast Component Object Model (COM) objects. ATL supports key COM features, including:

® Stock implementations of the interfaces IUnknown, IClassFactory, IClassFactory2, and IDispatch
® Dual interfaces
® Standard COM enumerator interfaces
® Connection points
® Tear-off interfaces
® ActiveX controls

You can use ATL code to create single-threaded objects, apartment-model objects, free-threaded model objects, or both free-threaded and apartment-model objects.

Standard Template Library

The Standard Template Library is a subset of the Standard C++ library. STL is a general-purpose library that contains template algorithms and container classes that work together to create application functionality. STL provides several of the most widely used containers, including lists, vectors, sets, and maps. The template algorithms include a number of essential data-manipulation tools for tasks such as searching, sorting, and merging.

STL provides libraries for the following functionality as shown in the table.

Use this STL library

To define this type of template

<algorithm> Numerous templates that implement useful algorithms


<deque> A class template that implements a deque container

<functional> Several templates that help construct predicates for the templates defined in <algorithm> and <numeric>

<iterator> Several templates that help define and manipulate iterators

<list> class template that implements a list container

<map> lass templates that implement associative containers

<memory> Several templates that allocate and free storage for various container classes

<numeric> Several templates that implement useful numeric functions

<queue> A class template that implements a queue container

<set> class template that implements an associative container with unique elements

<stack> class template that implements a stack container

<utility> everal templates of general utility

<vector> class template that implements a vector container



For more information about using STL, see the online documentation for the Standard C++ Library.

Creating Function Templates
A function template specifies a function that generalizes to arbitrary data types. This section discusses the details of function template definition as well as how to instantiate and override or "specialize" a function template.

This section includes the following topics:

Function Template Syntax

Function templates are composed of three elements:

® The template keyword
® A comma-delimited list of formal parameters, enclosed in angle brackets (<>)
® The function definition

A function that is generated from a template is sometimes called a templated function.

You can define function templates as extern, inline, or static, as you can any non-templated function.

The following example shows how you can code a function template for determining the lesser of two values:
// The template function works on numeric types.
template <class T>
T minimum (T& p1, T& p2)
{
return p1 <= p2 ? p1 : p2;
};

Angle Bracket Placement
Incorrect placement of angle brackets (<>) causes many template syntax errors. Make sure that you use proper spacing and parentheses to distinguish angle brackets from operators such as >> and –>. For example, the following code:

TempClass< float, a > b ? a : b > test1;

should be rewritten as:

TempClass< float, (a > b ? a : b) > test1;


Instantiating Function Templates
A function template specifies how to construct individual functions. This process of construction is called instantiation. A templated function is an instance of a function template.


To instantiate a function from a template, you supply data types as parameters to the function in your source code. The function is then instantiated when the code is compiled.

The compiler generates the code for each instantiation. Multiple declarations using the same data types will generate only one instance, but inline functions will generate multiple instances.

You use a templated function as you would any other function — that is, you can take the address of it as well as call it.

The following example code shows you how to define and use a function template:

template <class T>

T minimum (T& p1, T& p2)
{
return p1 <= p1 ? p1 : p2;
};
{
int a = 5, b = 10;
TRACE("the lesser of %d and %d is %d\n",
a,b,minimum(a, b));

double x = 5.9, y = 10.6;

TRACE("the lesser of %g and %g is %g\n",
x,y,minimum(x, y));
}

The compiler prevents the improper interaction of incompatible data types. If data types are incompatible, the compiler issues an error, as shown in the following example:

int x=2;
double d= 3.2;
swap(x,d); // Compiler Error:

Function templates are not limited to small functions. The following example code defines a template for the quicksort algorithm:

// Quicksort
// Function template that works on arbitrary data types.
// This function depends upon a swap function and
// a compare function, both which need to know
// how to operate on the targeted data type.
//
template <class Type>

void quicksort(Type* array, int loBound, int hiBound, int (*compfn)(Type,Type))
{
// stopping condition for recursion.
if (loBound >= hiBound)
return;

// the main algorithm.

int lo = loBound;
int hi = hiBound + 1; // increment now for a later pre-decrement.
Type elem = array[loBound];
for (;;)
{
// Compare elements here.
while ((lo<hiBound) && (compfn(array[++lo],elem)<0)) {}
while ((hi>loBound) && (compfn(array[--hi],elem)>0)) {}
if (lo < hi)
swap(array, lo, hi);
else
break;
}
swap(array, loBound, hi);
quicksort(array, loBound, hi-1, compfn);
quicksort(array, hi+1, hiBound, compfn);

}

Overriding Function Templates
You are not limited to using a function template as it is defined. You can define a unique behavior for a function by providing an explicit data-type specialization.

For example, consider a function template definition that compares two objects:
template<class T>
int compare(T a, T b)
{
return (a < b) ? -1 :(b < a) ? +1 : 0;
}

This template compares pointers but does not compare strings, so the template will not work as expected for char* data types. The solution for this case is to define a specialization of the compare function as follows:

int compare(char* a, char* b)
{
return stricmp(a,b);

No comments:

Post a Comment