class template specialization with signed/unsigned type problem

  • Thread starter andreas.schniertshauer
  • Start date
A

andreas.schniertshauer

Hello,

I have a class template of the following form:

template <typename T, typename F>
class Converter
{
public:
bool operator () (T& tTo, const F& tFrom) const;
};

And I want to do a specialization where F could be a long or unsigned long type:

template <>
class Converter<string, F>
{
public:
bool Converter<string, F>::eek:perator () ( string& tTo, const F& tFrom ) const
{
static_assert( std::is_integral<F>::value && (std::is_signed<F>::value || std::is_unsigned<F>::value), "Error: type not supported" );

...

if ( std::is_signed<F>::value )
{
// do something with long
}
else
if ( std::is_unsigned<F>::value )
{
// do something with unsigned long
}

...

return true;
}
};


Can anyone tell me please how I could write the specialized template class so that I could pass a long or unsigned long? Or isn't this possible to do in one class and I must write two specialized classes one specialization for long and one for unsigned long? I want to have less code, so the second solution would not be my favorite.

Thanks for the help,
Andreas.
 
V

Victor Bazarov

Hello,

I have a class template of the following form:

template <typename T, typename F>
class Converter
{
public:
bool operator () (T& tTo, const F& tFrom) const;
};

And I want to do a specialization where F could be a long or unsigned long type:

template <>
class Converter<string, F>
{
public:
bool Converter<string, F>::eek:perator () ( string& tTo, const F& tFrom ) const
{
static_assert( std::is_integral<F>::value && (std::is_signed<F>::value || std::is_unsigned<F>::value), "Error: type not supported" );

...

if ( std::is_signed<F>::value )
{
// do something with long
}
else
if ( std::is_unsigned<F>::value )
{
// do something with unsigned long
}

...

return true;
}
};
Can anyone tell me please how I could write the specialized template
class so that I could pass a long or unsigned long? Or isn't this
possible to do in one class and I must write two specialized classes
one specialization for long and one for unsigned long? I want to have
less code, so the second solution would not be my favorite.

I think what you need is a helper function that would *assume* that your
type is long or unsigned long, and then you need to create two
specializations, one for 'long', the other for 'unsigned long', and make
them both call that helper function. That way is much easier and
cleaner than all those ifs and static_asserts.

V
 
B

Blonder

did you mean something like this? Or what did you mean when you say assume?

template <typename T, typename F>
void ConverterHelper(T t, F f) {}

template <typename T>
void ConverterHelper<>(T t, unsigned long f) {}

template <typename T>
void ConverterHelper<>(T t, long f) {}
 
V

Victor Bazarov

did you mean something like this? Or what did you mean when you say assume?

template <typename T, typename F>
void ConverterHelper(T t, F f) {}

template <typename T>
void ConverterHelper<>(T t, unsigned long f) {}

template <typename T>
void ConverterHelper<>(T t, long f) {}

<sigh> It's difficult to answer without the context. Perhaps you could
at some point consider quoting the article to which you're replying...

First off, you had

template<class T, class F> class C { ...
bool operator() (T& to, const F& from);
};

to specialize it for 'F == long' or 'F == unsigned long' *in a single
function/class* is rather silly; you end up with lots of 'if' statements
and/or static asserts. So, don't do it. I suggested to specialize
twice, but then call some kind of helper class in which you can assume
that 'long' or 'unsigned long' is the "source" type. BTW, I remember
submitting something on a similar topic to the FAQ. Have you read the FAQ?

template<class T> class CH_long_ulong {
... // some common functionality
// maybe in the form of templates
};

template<class T> class C<T, long> : CH_long_ulong<T> {
public:
bool operator() (T& to, long from) {
CH_long_ulong<T>::common_part1(from);
.. // some special processing for 'long'
CH_long_ulong<T>::common_part2(from);
.. // some more special processing for 'long'
}
};

template<class T> class C<T, unsigned long>
: CH_long_ulong<T> {
public:
bool operator() (T& to, unsigned long from) {
CH_long_ulong<T>::common_part1(from);
.. // some special processing for 'unsigned long'
CH_long_ulong<T>::common_part2(from);
.. // some more special processing for 'unsigned long'
}
};

Hope this helps. Ask more questions.

V
 

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,961
Messages
2,570,130
Members
46,689
Latest member
liammiller

Latest Threads

Top