Boost logo

Boost :

From: Jonathan Turkanis (technews_at_[hidden])
Date: 2004-11-04 13:59:45

"James Harris" <james.harris_at_[hidden]> wrote in message
> Hello Boost Members,
> I have written a small library of meta-functions that allow rebinding of
> template arguments <snip> I am posting in an attempt to guage interest and
> hopefully receive pointers on the library proposal process.
> The library provides the following meta-functions:
> rebind<int index, class rebind_type, class source_type> -- rebind
> template arguments

To be MPL-friendly, it should be

   template<typename N, typename rebind_type, typename source_type>
   struct rebind;


> template <class A, class B, class C>
> class foo { };
> typedef foo<int, int, int> source_type;
> typedef rebind<1, char, source_type>::type rebound_type; // rebound_type
> equates to foo<int, char, int>

On two occassions recently I found myself implementing a
template-argument-rebinding facility and wished for a generic solution.
Unfortunately, I just looked at my two use cases and found that the metafunction
you describe would not be much help. Let me describe these cases, to give you an
idea of the problems which a generic rebind facility should IMO be able to

1) In my yet-to-be documented or posted "Format Lite" library -- a lightweight
alternative to Reece Dunne's recently reviewed Output Formatting library -- I
use class template specializations as CSS-type selectors to indicate the set of
classes which should receive a given formatting. E.g.,
      cout << punctuate< vector<string> >("[", ",", "]")
           << punctuate< vector<_> >("{", ",", "}");
The above code tells std::cout to format vectors of strings with square brackets
but all other vectors with curly brackets. I wanted to treat vector<_> and
vector<_, _> as equlivalent, so I wrote a metafunction rebind which takes a
template specialization T<P1, ..., Pn> and returns T<_, ..., _>. Using your
library, I would need to use an mpl iteration construct to implement this templa
te, and would also need to discover the arity of T (using
mpl::aux::template_arity). A much more efficient and straightforward solution is
to use a sequence of partial specializations, one for each arity.
The moral is that rebind should be able to rebind several template arguments at
2) For another yet-to-be posted library, I implemented a generic facility for
chaining user-defined policies to avoid increased instance size resulting from
multiple inheritance. (See )
The convention is that user-defined policies should be templates whose last
argument position is reserved for another policy, from which the user-defined
policy should derive. Now, given two policies P1 and P2, we can combine them as
 (i) if P1 is not a template instance (shame on the user!), return a policy
which derives indirectly from both P1 and P2.
 (ii) if P1 is a template specialization of the form T<Arg1, ...., Arg(n-1),
empty_base>, return
      T<Arg1, ...., Arg(n-1), P2>
 (iii) otherwise, if P1 is a template specialization of the form T<Arg1, ....,
Argn>, return
     T< Arg1, ..., combine<Argn, P2> >
Again, this is fairly straightforward to implement as a sequence of partial
specializations (two for each arity, this time), but your metafunction doesn't
help much.
I'm not sure there is a general solution to problems like the above, but I'd be
interested to see If you can come up with one.
> I have tested the code using MSVC 7.1 and GCC 3.3.2-1.
Have you tested it with templates that have default template arguments? GCC
notoriously will allow std::vector<char> to match the partial specialization
   template<template<typename> class T, typename P>
   struct foo< T<P> > { /* ... */ };
despite the fact that std::vector is a binary template.
> Kind Regards,
> James Harris.

Boost list run by bdawes at, gregod at, cpdaniel at, john at