template specialization on void*

P

petschy

hello all,

i'm trying to write a trait class (to generate an uint hash code for a
type):

template<typename T>
struct S
{
static unsigned int f(const T& t_);
};

template<typename T>
inline unsigned int S<T>::f(const T& t_)
{
// generic version using the bytes of T
}

the specializations for int, std::string work fine:

template<>
inline unsigned int S<unsigned int>::f(const unsigned int& s_);

template<>
inline unsigned int S<std::string>::f(const std::string& s_);

for void*, i get an error from gcc 4.1

template<>
inline unsigned int S<void*>::f(const void*& s_);

error: template-id 'f<>' for 'unsigned int S<void*>::f(const
void*&)' does not match any template declaration

i suspect the type of the f() arg is wrong, const void*& means const
reference to void* or reference to const void* ?

cheers, p
 
V

Victor Bazarov

petschy said:
i'm trying to write a trait class (to generate an uint hash code for a
type):

template<typename T>
struct S
{
static unsigned int f(const T& t_);
};

template<typename T>
inline unsigned int S<T>::f(const T& t_)
{
// generic version using the bytes of T
}

the specializations for int, std::string work fine:

template<>
inline unsigned int S<unsigned int>::f(const unsigned int& s_);

template<>
inline unsigned int S<std::string>::f(const std::string& s_);

for void*, i get an error from gcc 4.1

template<>
inline unsigned int S<void*>::f(const void*& s_);

error: template-id 'f<>' for 'unsigned int S<void*>::f(const
void*&)' does not match any template declaration

i suspect the type of the f() arg is wrong, const void*& means const
reference to void* or reference to const void* ?

It seems that what you're trying to do is to cv-qualify a 'void'.

Also, try dropping "template<>".

V
 
A

Andrey Tarasevich

petschy said:
i'm trying to write a trait class (to generate an uint hash code for a
type):

template<typename T>
struct S
{
static unsigned int f(const T& t_);
};

...
for void*, i get an error from gcc 4.1

template<>
inline unsigned int S<void*>::f(const void*& s_);

error: template-id 'f<>' for 'unsigned int S<void*>::f(const
void*&)' does not match any template declaration
...

Should be

template<> inline unsigned int S<void*>::f(void* const& s_);

You have 'const T&' with 'T = void*'. This unwraps into 'void* const&', not into
'const void*&'.
 
P

petschy

thanks, it compiles now.

if i write Hash<int*, int>, where int* is the key type and int is the
value type, then the default hash fn will be called. i must explicitly
set the trait with Hash<int*, int, Trait<void*> > to have the right fn
called.

is there a way to tell the compiler that for any pointer type i wish to
use the void* trait, without explicitly specifying it?

cheers, p
 
D

dasjotre

petschy said:
thanks, it compiles now.

if i write Hash<int*, int>, where int* is the key type and int is the
value type, then the default hash fn will be called. i must explicitly
set the trait with Hash<int*, int, Trait<void*> > to have the right fn
called.

is there a way to tell the compiler that for any pointer type i wish to
use the void* trait, without explicitly specifying it?

cheers, p

you need to specialize the class template

template<typename T>
struct S<T*>
{
static unsigned int f(T * const & t_)
{
your code for void *
}
};
 
P

petschy

dasjotre said:
you need to specialize the class template

template<typename T>
struct S<T*>
{
static unsigned int f(T * const & t_)
{
your code for void *
}
};

this doesn't seem to work. for int* keys, the compiler searches for
S<int*>, and won't find it, since i only provided implementation for
the specialization for void*. it should pick the void* specialization,
but now i'm not sure whether this is possible automatically, w/o
specifying the right trait type.

cheers, p
 
P

petschy

you need to specialize the class template
it works now :) omitted the specialization for void*, and provided
implementation for f(T* const&). this way all the pointer types will
have a separate function, which means code duplication. in this very
case it's not a problem, since the body of the fn is rather simple and
will be inlined anyway, but for other cases i still wonder how could
one instruct the compiler to use the void* implementation.

my solution:

template<>
inline S<void*>::f(void* const& t_)
{
return calculated hash by casting t_ to int and shifing
}

template<T>
inline S<T*>::f(T* const& t_)
{
return S<void*>::f(t_);
}

this approach would still work when the functions are more complex, but
the same for all pointer types. in that case, the general f()
implementation should be inlined, while the specialized void* not, to
avoid code bloat.

thanks for the replies.

cheers, p
 

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

Forum statistics

Threads
473,995
Messages
2,570,225
Members
46,815
Latest member
treekmostly22

Latest Threads

Top