template template parameter compilation errors!!!

A

aaragon

Hello guys,

I got a Mac and I'm trying to compile my code on Mac OS using GCC 4.3.
My code used to compile just fine in Ubuntu with the same compiler but
now it's giving me errors in all template template parameter code.
Anyone has an idea why this is happening???

The error message looks like the following:

element.h:494: error: type/value mismatch at argument 1 in template
parameter list for 'template<template<class, class> class MapPolicy>
class fea::TriangleGaussMap'
element.h:494: error: expected a template of type 'template<class,
class> class MapPolicy', got 'template<class _Key, class _Tp, class
_Compare, class _Alloc> class std::map'

part of the Implementation of that class follows:

template <
class TriangleGaussMap {

....

Thanks for the help!!!

aa
 
V

Victor Bazarov

aaragon said:
Hello guys,

I got a Mac and I'm trying to compile my code on Mac OS using GCC 4.3.
My code used to compile just fine in Ubuntu with the same compiler but
now it's giving me errors in all template template parameter code.
Anyone has an idea why this is happening???

FAQ 5.8.

V
 
I

Ian Collins

aaragon said:
Hello guys,

I got a Mac and I'm trying to compile my code on Mac OS using GCC 4.3.
My code used to compile just fine in Ubuntu with the same compiler but
now it's giving me errors in all template template parameter code.
Anyone has an idea why this is happening???

The error message looks like the following:

element.h:494: error: type/value mismatch at argument 1 in template
parameter list for 'template<template<class, class> class MapPolicy>
class fea::TriangleGaussMap'
element.h:494: error: expected a template of type 'template<class,
class> class MapPolicy', got 'template<class _Key, class _Tp, class
_Compare, class _Alloc> class std::map'
Without the full code it looks like you are not providing enough
template parameters in your declaration. std::map takes 4 parameters
and you only appear to be providing 4.

Older compilers where a bit lax when it cam to enforcing this and the
exactly matching requirements may be relaxed in the forthcoming
standard. For now, you have to provide the same number of template
parameters.
 
A

aaragon

Without the full code it looks like you are not providing enough
template parameters in your declaration. std::map takes 4 parameters
and you only appear to be providing 4.

Older compilers where a bit lax when it cam to enforcing this and the
exactly matching requirements may be relaxed in the forthcoming
standard. For now, you have to provide the same number of template
parameters.

What about default parameters? I could use for that class template
either the std::map, or a hash_map. They both have different number of
parameters, so why should I provide the total number of parameters?

aa
 
I

Ian Collins

*Please* don't quote signatures!
What about default parameters? I could use for that class template
either the std::map, or a hash_map. They both have different number of
parameters, so why should I provide the total number of parameters?
I don't think there is a simple solution. Your only option appears to
be to partially specialise hash_map to reduce the number of parameters.

Something like

#include <map>
#include <hash_map>

template <typename ItemType,
typename KeyType,
template <typename E,
typename K,
typename P = std::less<E>,
typename A = std::allocator<std::pair<const K,E> > >
class C>
struct X
{
C<ItemType,KeyType> c;
};

template <typename T>
struct Hash
{
bool operator()( const T&, const T&) const;
};

template <typename V,
typename K,
typename Compare = std::less<KeyType>,
typename Alloc = std::allocator<std::pair<const K,V> > >
struct HashMap : public std::hash_map<V,K,Hash<K>,Compare,Alloc>
{
using hash_map<V,K,Hash<K>,Compare,Alloc>::eek:perator[];
};

int main()
{
X<int,int,std::map> m;
X<int,int,std::multimap> mm;
X<int,int,HashMap> hm;

return 0;
}
 
A

Andrey Tarasevich

aaragon said:
...
What about default parameters? I could use for that class template
either the std::map, or a hash_map. They both have different number of
parameters, so why should I provide the total number of parameters?

Well, the thing is that in tis case you _can't_ use "either the std::map, or a
hash_map" if these templates accept different number of template arguments.

Just like default arguments in a function declaration don't change the fact that
a two-parameter function is still a two-parameter function (according to its type)

void foo(int, int = 2);

void (*p1)(int) = &foo; // ERROR
void (*p2)(int, int) = &foo; // OK

default template arguments in template declaration don't change the fact that a
4-parameter template is a 4-parameter template and it will not pass as an
argument for a 2-parameter template template parameter.

If you want to stick with 2-parameter template template parameter and still be
able to use 'std::map' or 'hash_map' as arguments, you'll have to use an
appropriate template trick, of which there are many.

For example, consider how I do it in the following code sample

template <typename S, typename D> struct std_map_adaptor {
typedef std::map<S, D> type;
};

template <typename S, typename D> struct hash_map_adaptor {
typedef hash_map<S, D> type;
};

template < template <class,class> class MapPolicy = std_map_adaptor>
class TriangleGaussMap
{
public:
void foo()
{
typename MapPolicy<int, double>::type map;
// Note the use of nested typename 'type'

map[0] = 5;
map[1] = 3.5;
map[2] = 8.1;
}
};

int main()
{
TriangleGaussMap<> map1;
map1.foo();

TriangleGaussMap<hash_map_adaptor> map2;
map2.foo();
}
 
A

aaragon

aaragon said:
...
What about default parameters? I could use for that class template
either the std::map, or a hash_map. They both have different number of
parameters, so why should I provide the total number of parameters?

Well, the thing is that in tis case you _can't_ use "either the std::map, or a
hash_map" if these templates accept different number of template arguments.

Just like default arguments in a function declaration don't change the fact that
a two-parameter function is still a two-parameter function (according to its type)

void foo(int, int = 2);

void (*p1)(int) = &foo; // ERROR
void (*p2)(int, int) = &foo; // OK

default template arguments in template declaration don't change the fact that a
4-parameter template is a 4-parameter template and it will not pass as an
argument for a 2-parameter template template parameter.

If you want to stick with 2-parameter template template parameter and still be
able to use 'std::map' or 'hash_map' as arguments, you'll have to use an
appropriate template trick, of which there are many.

For example, consider how I do it in the following code sample

template <typename S, typename D> struct std_map_adaptor {
typedef std::map<S, D> type;
};

template <typename S, typename D> struct hash_map_adaptor {
typedef hash_map<S, D> type;
};

template < template <class,class> class MapPolicy = std_map_adaptor>
class TriangleGaussMap
{
public:
void foo()
{
typename MapPolicy<int, double>::type map;
// Note the use of nested typename 'type'

map[0] = 5;
map[1] = 3.5;
map[2] = 8.1;
}
};

int main()
{
TriangleGaussMap<> map1;
map1.foo();

TriangleGaussMap<hash_map_adaptor> map2;
map2.foo();
}

Yes, I see the trick, that'll do it. However, it's kind of annoying
having to write code to support something that I've been using for a
while. With an earlier version of GCC, I was able to chose either a
std::map or a gnu::hash_map very easily. Thanks for the info.

aa
 

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,763
Messages
2,569,562
Members
45,038
Latest member
OrderProperKetocapsules

Latest Threads

Top