    Although it's perfectly acceptable to derive an ordinary class from a
class template, the resulting class of course has limited generality compared
to its template base class. If generality is important, it's probably a better
idea to derive a class template from a class template. This allows us to
extend an existing class template with new functionality or to override the
functionality of the existing class template.

    The class template tt(SortVector) presented below is derived from the
existing class template tt(std::vector). It allows us to perform a
emi(hierarchic sort) of its elements using any ordering of any data members
its data elements may contain. To accomplish this there is but one
requirement. tt(SortVector)'s data type must offer dedicated member
functions comparing its members.

    For example, if tt(SortVector)'s data type is an object of class
tt(MultiData), then tt(MultiData) should implement member functions having the
following prototypes for each of its data members which can be compared:
        verb(    bool (MultiData::*)(MultiData const &rhv))

So, if tt(MultiData) has two data members, tt(int d_value) and
tt(std::string d_text) and both may be used by a hierarchic sort, then
tt(MultiData) should offer the following two members:
        verb(    bool intCmp(MultiData const &rhv);  // returns d_value < rhv.d_value
    bool textCmp(MultiData const &rhv); // returns d_text  < rhv.d_text)

Furthermore, as a convenience it is assumed that oplshift() and
oprshift() have been defined for tt(MultiData) objects.

    The class template tt(SortVector) is directly derived from the template
class tt(std::vector). Our implementation inherits all members from that base
class. It also offers two simple constructors:
        verbinclude(//HEAD examples/template2template.cc)

    Its member tt(hierarchicSort) is the true em(raison d'\^etre) for the
class. It defines the hierarchic sort criteria. It expects
        hi(sort criteria: hierarchic sorting)
    a pointer to a series of pointers to member functions of the class
tt(Type) as well as a tt(size_t) representing the size of the array.

 The array's first element indicates tt(Type)'s most significant sort
criterion, the array's last element indicates the class's least significant
sort criterion. Since the ti(stable_sort) generic algorithm was designed
explicitly to support hierarchic sorting, the member uses this generic
algorithm to sort tt(SortVector)'s elements. With hierarchic sorting, the
least significant criterion should be sorted first. tt(hierarchicSort)'s
implementation is therefore easy. It requires a support class tt(SortWith)
whose objects are initialized by the addresses of the member functions passed
to the tt(hierarchicSort()) member:
        verbinclude(//SORT examples/template2template.cc)

    The class tt(SortWith) is a simple wrapper class around a pointer to
a predicate function. Since it depends on tt(SortVector)'s actual data
type the class tt(SortWith) must also be a class template:
        verbinclude(//SORTWITH examples/template2template.cc)

 tt(SortWith)'s constructor receives a pointer to a predicate function and
initializes the class's tt(d_ptr) data member:
        verbinclude(//SORTCONS examples/template2template.cc)

    Its binary predicate member (tt(operator())) must return tt(true) if its
first argument should eventually be placed ahead of its second argument:
        verbinclude(//OPERATOR examples/template2template.cc)

    The following examples, which can be embedded in a tt(main)
function, provides an illustration:
    itemization(
    it() First, A tt(SortVector) object is created for tt(MultiData) objects.
It uses the ti(copy) generic algorithm to fill the tt(SortVector) object from
information appearing at the program's standard input stream. Having
initialized the object its elements are displayed to the standard output
stream:
        verbinclude(//MAIN1 examples/template2template.cc)
    it() An array of pointers to members is initialized with the addresses of
two member functions. The text comparison is the most significant sort
criterion:
        verbinclude(//ARRAY examples/template2template.cc)
    it() Next, the array's elements are sorted and displayed to the standard
output stream:
        verbinclude(//SORT1 examples/template2template.cc)
    it() Then the two elements of the array of pointers to tt(MultiData)'s
member functions are swapped, and the previous step is repeated:
        verbinclude(//SORT2 examples/template2template.cc)
    )
    After compiling the program the following command can be given:
        verb(    echo a 1 b 2 a 2 b 1 | a.out)

This results in the following output:
        verb(    a 1 b 2 a 2 b 1
    ====
    a 1 a 2 b 1 b 2
    ====
    a 1 b 1 a 2 b 2
    ====)

