|
Boost : |
Subject: Re: [boost] Design conventions; passing functors
From: Joachim Faulhaber (afojgo_at_[hidden])
Date: 2008-12-01 12:30:19
2008/11/29 Neal Becker <ndbecker2_at_[hidden]>:
> I used to like template template, but I've decided it's fairly useless. The problem is:
>
> template<template<class A>a>
> does not match a class with a default parameter. So, for example, suppose you have a class where you specify a container class as a parameter. For example:
>
> template<typename T, template<class Vec> vec >
> class my_class ...
>
> This won't match
> my_class<int, std::vector>
>
> Because std::vector has a defaulted alloc parameter. This ruins the design (my_class shouldn't need to know anything about default parameters of the container. How could it know what other vector-like classes there could be and what default parameters they might have?)
>
That's an interesting point, you are making, which I had not realized
clearly before.
Using template type parameters, there is a much bigger set
of possible instance types, vector implementations in your example.
With template template parameters the match must be exact:
template<class T,
// matches only binary vector templates
template<class,class>class Vec,
class A = std::allocator<T> >
class my_class
{
public:
typedef Vec<T,A> vec_type;
my_class():_vec(1,static_cast<T>(42))
{ std::cout<<"Aswer: "<<_vec[0]<<endl; }
private:
vec_type _vec;
};
void template_default_problem()
{ my_class<double, std::vector> myInst; }
Yet, I did not deliberately become a template template
afficionado. They helped me to solve a problem in
my library design. I intended to design interval container
template parameters as closely as possible to their
std::container cousins.
Here is a simplified version of interval_set:
template<class T,
class C = std::less<T>,
class A = std::allocator<T> >
class interval_set
{
public:
typedef
std::set<interval<T>,
exclusive_less<interval<T> >
A::allocator_template<interval<T> >//error
> impl_type; // ^^^^ No language support
typedef std::set<T,C,A> atomized_type;
// Return the interval set as a set of elements
void atomize(atomized_type& atomized);
...
private:
impl_type impl_set;
};
In order to implement things like the atomize function
that returns the interval set as a set of elements I
needed to instantiate the allocator template for different
instance types: interval- and element-types.
This is made possible by using template template:
template<
class T,
class C = std::less<T>,
template<class>class A = std::allocator
>
class my_interval_set
{
public:
typedef
std::set<interval<T>,
exclusive_less<interval<T> >
A<interval<T> > //ok now
> impl_type;
typedef
std::set<T,C,
A<T> //Same allocator,
//different instances
> atomized_type;
// Return the interval set as a set of elements
void atomize(atomized_type& atomized);
...
private:
impl_type impl_set;
};
So far template template params has helped me a lot and,
yes, I still like them ;-) But I also realize a growing
list of downsides, to which you have added one more
item.
Cheers Joachim
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk