> Matthew wrote:
>
> >However, modern template practices have revived the use for MI, in so far as
> >being able to apply tag inheritance to existing types via bolt-in templates.
> >D doesn't properly support this at the moment, though I have no doubt that
> >it will.
> > 
> >
> What is tag inheritance?
 
    template< typename S
            , typename T = sequence_range_traits<S, is_const<S>::value>
            >
    class sequence_range
      : public iterable_range_tag // <== ** this is the tag **
    {
    public:
      . . .
 
The tag identifies the range type, which is used in the range algorithms for selecting the most efficient algorithms.
 
The tags look like the following:
 
    struct simple_range_tag
    {};
 
    struct iterable_range_tag
      : public simple_range_tag
    {};
 
    struct noninterruptible_range_tag
    {};
 
[This is an extract from the STLSoft implementation of the Range concept, which I'm working on with John Torjo. Ranges will also likely feature large in DTL, although at the moment I've only got so far as doing the basic list, map, queue, set, stack and vector class implementations, and exchanging vague ponderings with big-W. As soon as he gets back from SDWest I expect to see a rapid movement
 
> What are bolt-in templates?
 
From [Wils04]:
 

 

Definition: Bolt-ins

Bolt-ins are template classes with the following characteristics:

1. They derive, usually publicly, from their primary parameterising type.

2. They accommodate the polymorphic nature of their primary parameterising type. Usually they also adhere to the nature, but this is not always the case, and they may define virtual methods of their own, in addition to overriding those defined by the primary parameterising type.

3. They may increase the footprint of the primary parameterising type by the definition of member variables, virtual functions and additional inheritance from non-empty types.

 

>
> Just out of interest could you give an example?
Classic examples are to be found in ATL, whereby several separate template classes may provide bolt-in behaviour, i.e. CComObject<>, CComObjectStack<>, etc.
 
 
A (really stupid) simple example (in C++):
 
class NumSequence
{
public:
  void PresentCalculation(ostream &os, int maxValue)
  {
    vector<int> things(this->CalcThings(maxValue));
 
    copy(things.begin(), things.end(), ostream_iterator<int>(os));
  }
 
protected:
  virtual vector<int> CalcThings(int maxValue) = 0;
};
 
template<typename S>
class FibonacciSequence
{
protected:
  virtual vector<int> CalcThings(int maxValue)
  {
    . . . calculate a Fibonacci sequence up to maxValue, and return in vector<int>
  }
};
 
template<typename S>
class PrimeSequence
{
protected:
  virtual vector<int> CalcThings(int maxValue)
  {
    . . . calculate a prime number sequence up to maxValue, and return in vector<int>
  }
};
 
 
int main()
{
  FibonacciSequence<NumSequence> ps().PresentCalculation(cout);
  PrimeSequence<NumSequence> ps().PresentCalculation(cout);
  return 0;
}
 
I'll leave it to all your great minds to figure out the amazing real-world benefits of this technique, rather than just my weak example.
 
In [Wils04], the sections in the Bolt-ins chapter are:
 
    22.1 Adding Functionality
    22.2 Skin Selection
    22.3 Non-virtual Overriding
    22.4 Leveraging Scope
    22.5 Simulated Compile-time Polymorphism
    22.6 Parameterised Polymorphic Packaging.
 
And if you want to know any more than that, you'll have to buy it (probably available around Sept/Oct). :)