Reputation: 62323
I'm having a problem which I'm sure is simple to fix but I'm at a loss...
I have a template that performs the following code:
T value = d;
if ( std::numeric_limits< T >::is_signed )
{
if ( value < 0 )
{
*this += _T( "-" );
value = -(signed)value;
}
}
Now for, obvious reasons, GCC is giving me a warning (comparison is always false due to limited range of data type) when this code is compiled for an unsigned type. I fully understand the reasoning behind this and I put in the numeric_limits check to see if I could get the compiler to shut up about it (it worked for MSVC). Alas under GCC I get the warning. Is there any way (short of disabling the warning which I don't even know if you can do with GCC) to fix this warning? The code will never get called anyway and I would assume the optimiser will compile it out as well but I can't get rid of the warning.
Can someone give me a solution to this?
Cheers!
Upvotes: 5
Views: 1906
Reputation: 17784
See https://stackoverflow.com/a/8658004/274937 for the real solution, which allows suppressing -Wtype-limits warnings case-by-case. In short, just wrap each comparison, which generates the warning, into a dummy function.
Upvotes: 3
Reputation: 223999
Can someone give me a solution to this?
Nothing revolutionary, but I usually do this by overloading. Something along those lines:
//Beware, brain-compiled code ahead!
template< bool B >
struct Bool { const static bool result = B; }
template< typename T >
void do_it(T& , Bool<false> /*is_signed*/)
{
// nothing to do for unsigned types
}
template< typename T >
void do_it(T& value, Bool<true> /*is_signed*/)
{
if ( value < 0 ) {
*this += _T( "-" );
value = -(signed)value;
}
}
template< typename T >
void do_something(T& value)
{
do_it(value, Bool<std::numeric_limits< T >::is_signed>() );
}
If you can use class templates instead of function templates, you can use specialization instead of overloading. (There is no function template partial specialization, which makes specializing function templates a bit more of a hassle.)
Upvotes: 3
Reputation: 179779
Simpler solution:
template <typename T> inline bool isNegative(T value) {
return std::numeric_limits< T >::is_signed && value < 0; // Doesn't trigger warning.
}
T value = d;
if ( isNegative(value) ) // Doesn't trigger warning either.
{
*this += _T( "-" );
value = -1 * value;
}
Upvotes: 5
Reputation: 13182
You can specialize your function like this:
template <bool S>
void manipulate_sign(T&) {}
template <>
void manipulate_sign<true>(T& value) {
if ( value < 0 )
{
*this += _T( "-" );
value = -(signed)value;
}
}
//then call like this:
manipulate_sign<std::numeric_limits< T >::is_signed>();
Just disabling the warning might be better though.
Upvotes: 2