
2008/11/29 Neal Becker <ndbecker2@gmail.com>:
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