By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
454,340 Members | 1,988 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 454,340 IT Pros & Developers. It's quick & easy.

template specialization on void*

P: n/a
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

Nov 13 '06 #1
Share this Question
Share on Google+
6 Replies


P: n/a
petschy wrote:
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
Nov 13 '06 #2

P: n/a
petschy wrote:
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
Nov 14 '06 #3

P: n/a
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

Nov 14 '06 #4

P: n/a

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

Nov 14 '06 #5

P: n/a

dasjotre wrote:
petschy wrote:
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

Nov 14 '06 #6

P: n/a
you need to specialize the class template

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

Nov 14 '06 #7

This discussion thread is closed

Replies have been disabled for this discussion.