Template name as template parameter (or something like that)

J

Jon

Normally I can search and find answers to things like this but with this
one I'm not even sure what to search for and haven't had any luck. Anyway,
I'm trying to use a template name as a template parameter and can't seem
to figure out what I need to do. Code follows:

template <class MAPTYPE, class KEYTYPE, class VALUETYPE> class double_map
{
MAPTYPE<KEYTYPE,VALUETYPE> forward_; // for "forward" lookups
MAPTYPE<VALUETYPE,KEYTYPE> reverse_; // for "reverse" lookups

....

So I want to use MAPTYPE (which is a template itself) within this template
to specialize on the KEYTYPE and VALUETYPE parameters. For example, want
I want to be able to do something like:

double_map<hash_map, string, int> mymap;

or

double_map<unordered_map, string, int> mymap;

etc...

I can't seem to work out what I need to do to achieve this and keep the
syntax nice.

Any help would be appreciated.
 
J

Jon

What you want is for that first parameter to be a template and not a
type. So define the template that way:

template <template<class, class> class maptype, class keytype, class
valuetype> ...

Ah, thanks! I had tried something similar but I was trying to use a name
for other template parameters instead of just template said:
By the way, hash_map almost certainly won't work here, because it
probably takes more then two template arguments, with all but the first
two having defaults. Welcome to the wonderful world of template template
parameters.

Yep, you're right. Wow this is actually pretty nasty because I'd rather
use the default values of whatever template type is specified. Not so
straightforward and a little too verbose for what I wanted.
Incidentally, a more verbose approach is used in the standard library
(whose interface pre-dated template template parameters). Use your
original definition, and instantiate it with the right type:

double_map<hash_map<string, int>, string, int> mymap;

The problem with this is that it would actually need the reverse type too:

double_map<hash_map<string, int>, hash_map<int, string>, string, int>
mymap;

_Really_ verbose and annoying for sure. :)

Thanks!
 
S

SG

template <template<class, class> class maptype, class keytype, class
valuetype> ...

By the way, hash_map almost certainly won't work here, because it
probably takes more then two template arguments, with all but the first
two having defaults. Welcome to the wonderful world of template
template parameters.

G++ seems to like the following code even with -Wall and -pedantic. In
the function "fun" the template class D ist instantiated with
"SuperMap" as a template template parameter that has a third template
parameter with a default (T3 = int).

template<typename KEY, typename MTYPE, typename T3 = int>
class SuperMap {};

template< template<typename,typename> class MAP,
typename K, typename V>
class D {
MAP<K,V> t1;
MAP<V,K> t2;
};

void fun() {
// D wants: template<class,class>
// it gets: template<class,class,class=int>
D<SuperMap,int,int> d();
}

Is this really not supported by the C++ standard officially?
Incidentally, a more verbose approach is used in the standard library
(whose interface pre-dated template template parameters). Use your
original definition, and instantiate it with the right type:

double_map<hash_map<string, int>, string, int> mymap;

In that case you need some kind of "rebinding" functionality
(MAPTYPE::rebind<VAL,KEY>::type) to make it work. --- or just another
template parameter for the 2nd map type.


Cheers!
SG
 
J

Joe Smith

Pete Becker said:
G++ seems to like the following code even with -Wall and -pedantic. In
the function "fun" the template class D ist instantiated with
"SuperMap" as a template template parameter that has a third template
parameter with a default (T3 = int).

template<typename KEY, typename MTYPE, typename T3 = int>
class SuperMap {};

template< template<typename,typename> class MAP,
typename K, typename V>
class D {
MAP<K,V> t1;
MAP<V,K> t2;
};

void fun() {
// D wants: template<class,class>
// it gets: template<class,class,class=int>
D<SuperMap,int,int> d();
}

Is this really not supported by the C++ standard officially?

See the example in [temp.arg.template] /2.
The example you are referring to is not present in C++03. It is present in
the lastest working draft.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,580
Members
45,054
Latest member
TrimKetoBoost

Latest Threads

Top