N
Niklas Norrthon
I've been banging my head in the wall for some time now over a
little problem having to do with partial specialization of
function templates.
The real problem is more complex than this, but after trimming
out irrelevant stuff, this is what remains. The problem is to
have a function template with different specialization for
signed an unsigned template parameters. Lets assume for now that
I want to test signed arguments for negative values and do
something special with these cases, while unsigned arguments
should not be tested at all.
Consider the following code:
#include <iostream>
#include <limits>
/*
* Helper function called by f<IntType>.
*/
template <typename IntType, bool is_signed> void g(IntType x);
/* Now I want to have two specializations of the above: */
template <typename IntType>
void g<IntType, true>(IntType x) /* Signed types end up here */
{
if (x < 0) { /* ok, x is signed */
/* Special logic here */
}
}
template <typename IntType>
void g<IntType, false>(IntType)
{
/* x is unsigned, so don't have to do anything */
}
/*
* Function called by main. Only template parameter
* is the IntType.
*/
template <typename IntType>
void
f(IntType x)
{
#if 0
/* This would result in compiler warnings if IntType is unsigned: */
if (numeric_limits<IntType>::is_signed && x < 0) {
/* special logic here */
}
#else
/* So let's try this instead */
g<IntType, numeric_limits<IntType>::is_signed>(x);
#endif
/* More logic here */
}
int
main()
{
unsigned char uc = -1;
unsigned short us = -1;
unsigned int ui = -1;
unsigned long ul = -1L;
signed char sc = -1;
signed short ss = -1;
signed int si = -1;
signed long sl = -1L;
f(uc);
f(us);
f(ui);
f(ul);
f(sc);
f(ss);
f(si);
f(sl);
return 0;
}
The compiler complains with the following message:
foo.cc:11: error: function template partial specialization
'g<IntType, true>' is not allowed
I'd appreciate some hints how to get on.
When this is solved I'll have to deal with right shifting:
typedef unsigned short MyInt;
const MyInt my_int_mask = -1;
template <typename UnsignedIntType>
void f(UnsignedIntType x)
{
while (x > 0) {
MyInt y = x /* & my_int_mask */;
/* do something with y */
/* next line does not work if sizeof y >= sizeof x */
x >>= numeric_limits<MyInt>::digits; /* more template magic needed */
}
}
/Niklas Norrthon
little problem having to do with partial specialization of
function templates.
The real problem is more complex than this, but after trimming
out irrelevant stuff, this is what remains. The problem is to
have a function template with different specialization for
signed an unsigned template parameters. Lets assume for now that
I want to test signed arguments for negative values and do
something special with these cases, while unsigned arguments
should not be tested at all.
Consider the following code:
#include <iostream>
#include <limits>
/*
* Helper function called by f<IntType>.
*/
template <typename IntType, bool is_signed> void g(IntType x);
/* Now I want to have two specializations of the above: */
template <typename IntType>
void g<IntType, true>(IntType x) /* Signed types end up here */
{
if (x < 0) { /* ok, x is signed */
/* Special logic here */
}
}
template <typename IntType>
void g<IntType, false>(IntType)
{
/* x is unsigned, so don't have to do anything */
}
/*
* Function called by main. Only template parameter
* is the IntType.
*/
template <typename IntType>
void
f(IntType x)
{
#if 0
/* This would result in compiler warnings if IntType is unsigned: */
if (numeric_limits<IntType>::is_signed && x < 0) {
/* special logic here */
}
#else
/* So let's try this instead */
g<IntType, numeric_limits<IntType>::is_signed>(x);
#endif
/* More logic here */
}
int
main()
{
unsigned char uc = -1;
unsigned short us = -1;
unsigned int ui = -1;
unsigned long ul = -1L;
signed char sc = -1;
signed short ss = -1;
signed int si = -1;
signed long sl = -1L;
f(uc);
f(us);
f(ui);
f(ul);
f(sc);
f(ss);
f(si);
f(sl);
return 0;
}
The compiler complains with the following message:
foo.cc:11: error: function template partial specialization
'g<IntType, true>' is not allowed
I'd appreciate some hints how to get on.
When this is solved I'll have to deal with right shifting:
typedef unsigned short MyInt;
const MyInt my_int_mask = -1;
template <typename UnsignedIntType>
void f(UnsignedIntType x)
{
while (x > 0) {
MyInt y = x /* & my_int_mask */;
/* do something with y */
/* next line does not work if sizeof y >= sizeof x */
x >>= numeric_limits<MyInt>::digits; /* more template magic needed */
}
}
/Niklas Norrthon