我遇到了一个问题,我确信这个问题很容易解决,但我很茫然......
我有一个执行以下代码的模板:
T value = d;
if ( std::numeric_limits< T >::is_signed )
{
if ( value < 0 )
{
*this += _T( "-" );
value = -(signed)value;
}
}
现在明显的原因是,当为无符号类型编译此代码时,GCC正在给我一个警告(由于数据类型的范围有限,比较总是假的)。我完全理解这背后的原因,我在numeric_limits检查中查看是否可以让编译器关闭它(它适用于MSVC)。在海湾合作委员会下,我得到了警告。有没有办法(没有禁用警告,我甚至不知道你是否可以使用GCC)来修复此警告?代码永远不会被调用,我会假设优化器也会将其编译出来,但我无法摆脱警告。
有人可以给我解决方案吗?
干杯!
答案 0 :(得分:5)
更简单的解决方案:
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;
}
答案 1 :(得分:3)
有人可以给我解决方案吗?
没什么革命性的,但我通常是通过重载来做到这一点。这些方面的东西:
//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>() );
}
如果您可以使用类模板而不是函数模板,则可以使用特化而不是重载。 (没有功能模板部分特化,这使得专业化功能模板更加麻烦。)
答案 2 :(得分:3)
请参阅https://stackoverflow.com/a/8658004/274937了解真实解决方案,该解决方案允许逐个取消 -Wtype-limits 警告。简而言之,只需将生成警告的每个比较包装成虚函数。
答案 3 :(得分:2)
您可以像这样专门化您的功能:
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>();
虽然禁用警告可能会更好。