Connecting Tech Pros Worldwide Help | Site Map

template specialization on void*

petschy
Guest
 
Posts: n/a
#1: Nov 13 '06
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

Victor Bazarov
Guest
 
Posts: n/a
#2: Nov 13 '06

re: template specialization on void*


petschy wrote:
Quote:
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
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask


Andrey Tarasevich
Guest
 
Posts: n/a
#3: Nov 14 '06

re: template specialization on void*


petschy wrote:
Quote:
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*&'.

--
Best regards,
Andrey Tarasevich
petschy
Guest
 
Posts: n/a
#4: Nov 14 '06

re: template specialization on void*


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

dasjotre
Guest
 
Posts: n/a
#5: Nov 14 '06

re: template specialization on void*



petschy wrote:
Quote:
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 *
}
};

petschy
Guest
 
Posts: n/a
#6: Nov 14 '06

re: template specialization on void*



dasjotre wrote:
Quote:
petschy wrote:
Quote:
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 *
}
};
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

petschy
Guest
 
Posts: n/a
#7: Nov 14 '06

re: template specialization on void*


you need to specialize the class template
Quote:
Quote:

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

Closed Thread