У меня есть проблема, которая я уверен, просто зафиксировать, но я в замешательстве...
У меня есть шаблон, который выполняет следующий код:
T value = d;
if ( std::numeric_limits< T >::is_signed )
{
if ( value < 0 )
{
*this += _T( "-" );
value = -(signed)value;
}
}
Теперь для, очевидные причины, GCC дает мне предупреждение (сравнение является всегда ложью из-за ограниченного диапазона типа данных), когда этот код компилируется для неподписанного типа. Я полностью понимаю обоснование позади этого, и я вставил проверку numeric_limits, чтобы видеть, мог ли я заставить компилятор замолчать об этом (это работало на MSVC). Увы под GCC я получаю предупреждение. Есть ли какой-либо путь (за исключением отключения предупреждения, которое я даже не знаю, можно ли сделать с GCC) зафиксировать это предупреждение? Код никогда не будут называть так или иначе, и я предположил бы, что оптимизатор скомпилирует его также, но я не могу избавиться от предупреждения.
Кто-то может дать мне решение этого?
Удачи!
Более простое решение:
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;
}
Вы можете настроить свою функцию следующим образом:
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>();
Хотя может быть лучше просто отключить предупреждение.
Может ли кто-нибудь дать мне решение этой проблемы?
Ничего революционного, но обычно я делаю это путем перегрузки. Что-то в этом роде:
//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>() );
}
Если вы можете использовать шаблоны классов вместо шаблонов функций, вы можете использовать специализацию вместо перегрузки. (Частичная специализация шаблонов функций отсутствует, что затрудняет специализацию шаблонов функций.)