Velocity Reviews

Velocity Reviews (http://www.velocityreviews.com/forums/index.php)
-   C++ (http://www.velocityreviews.com/forums/f39-c.html)
-   -   class template specialization with signed/unsigned type problem (http://www.velocityreviews.com/forums/t948925-class-template-specialization-with-signed-unsigned-type-problem.html)

andreas.schniertshauer@googlemail.com 08-01-2012 12:33 PM

class template specialization with signed/unsigned type problem
 
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>::operator () ( 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.

Victor Bazarov 08-01-2012 01:06 PM

Re: class template specialization with signed/unsigned type problem
 
On 8/1/2012 8:33 AM, andreas.schniertshauer@googlemail.com wrote:
> 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>::operator () ( 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
--
I do not respond to top-posted replies, please don't ask

Blonder 08-01-2012 02:04 PM

Re: class template specialization with signed/unsigned type problem
 
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) {}

Victor Bazarov 08-01-2012 03:03 PM

Re: class template specialization with signed/unsigned type problem
 
On 8/1/2012 10:04 AM, Blonder wrote:
> 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
--
I do not respond to top-posted replies, please don't ask


All times are GMT. The time now is 06:23 AM.

Powered by vBulletin®. Copyright ©2000 - 2014, vBulletin Solutions, Inc.
SEO by vBSEO ©2010, Crawlability, Inc.