Triggered by Debian bug #362220 [0] I submitted GCC bug report #27178 [1] only to be told that container.h made use of a GCC extension that will have been removed from GCC in the upcoming 4.2.0 release [2]. Basically, where we were simply writing this:
template <template <class> class> class container; typedef container<std::list> lst;
we now have to write the more cumbersome:
template <template <class, class> class> class container; typedef container<std::list> lst;
This is because std::list has two template parameters, the element type and the allocator type. Ugh.
Hi, I saw the same problem coming in my own project, so I made some provisional changes in my own source to help. I don't know if my technique is directly applicable to your particular situation, but it might provide some ideas for a workaround. I wrote a forward declaration header for each class template definition in STL. Example: // \file "util/STL/allocator_fwd.h" ------------------------------------ namespace std { template <typename> class allocator; } // \file "util/STL/list_fwd.h" ----------------------------------------- #include "util/STL/allocator_fwd.h" namespace std { template <class T, class Alloc> class list; } namespace not_std { template <class T> struct default_list { typedef std::list<T, std::allocator<T> > type; }; } //---------------------------------------------------------------------- When I want to name the default std::list<T> type without without requiring its complete type, I can refer to default_list<T>::type, which has explicitly bound the trailing template arguments to their STL defaults. Advantage: avoids including <list> in certain headers where the complete type is not needed (e.g. return types, pointer/reference to... uses). And how does this relate to your container<T> ...
It's ugly, because the intent was clearly to not bother the user with implementation details like the allocator. From the user's perspective, the intent is to express "container of T", never mind what type of container. I've attached a patch against CVS GiNaC-1.3 that converts all places flaged as errors in GCC 4.2 20060415 (experimental) to:
template <template <class T, class = std::allocator<T> > class> class X; typedef X<std::list> lst;
The situation described above is a workaround to the lack of "template typedefs" in (present) std C++, which is our common underlying problem. A kludgy variation might use inheritance, but this doesn't result in equivalent types: namespace not_std { template <class T> class default_list : public std::list<T, std::allocator<T> > { typedef std::list<T, std::allocator<T> > type; }; } (This, however, does require std::list's complete definition.) You could then write something like this (using your example): template <template <class> class> class X; typedef X<not_std::default_list> lst; Again, not the greatest solution because of the inheritance relationship separating you from the actualy type you want. Rewriting your definitions to use a nested ::type member might only work for these non_std wrappers because the STL containers don't have self-referential 'type' member typedefs.
This is ugly as sin, because I don't think that we really wanted to express "STL-container of T", as the changed code now appears to imply.
Any suggestions?
I might see what other template metaprogramming techniques have to offer. I'm only a newbie in this subject, still learning on the fly. I would be very interested to hear what solution you end up using. David Fang