Тестирование подписи параметра шаблона
Мне нужно замаскировать некоторые ведущие биты значения. Если значение без знака, я могу утверждать (гарантировать), что некоторое произвольное количество старших битов не установлено, то есть значение гарантированно будет ограничено.
Если он подписан, мне нужно замаскировать начальные биты (превращая значение в некоторую непереносимую кучу битов, да, я знаю об этом:-)). Я хотел бы сохранить операцию маскирования, если значение не подписано.
Так что у меня в основном есть
template<typename T, some more template parameters>
class {
unsigned transform(T value) {
...
if (isSigned(T)) {
value &= mask;
}
...
}
}
Существует ли простой способ написать isSigned(), который можно оценить во время компиляции (чтобы оптимизатор мог удалить неподписанный мертвый код)?
Конечно, я мог бы добавить еще один параметр шаблона...
3 ответа
Да. Вы должны использовать частичную специализацию:
template <bool> struct impl { static void foo(); };
template <> struct impl<true> { static void foo(); };
template <typename T> struct Foo
{
void do_magic(T const &)
{
impl<std::is_signed<T>::value>();
// ...
}
};
Вы можете использовать готовые is_signed
класс черты от <type_traits>
вместо того, чтобы катиться самостоятельно.
if (T(-1) < T(0))
Но я бы добавил это в параметр шаблона и использовал его для специализации, а не для условного кода. Условный код, основанный на параметрах шаблона, часто приводит к ложным предупреждениям компилятора, таким как "недоступный код" или "константное выражение в условии".
Что-то вроде:
template <typename T, bool is_signed>
inline void apply_mask_helper(T& value) { value &= mask; }
template <typename T>
inline void apply_mask_helper<T, false>(T&) { }
template <typename T>
inline void apply_mask(T& value) { apply_mask_helper<T, T(-1) < T(0)>(value); }
Использование numeric_limits
от limits
заголовок:
if(numeric_limits<T>::is_signed) { … }
Как сказал Керрек, я бы пошел с частичной специализацией. В противном случае компилятор может жаловаться, что значение условия известно во время компиляции.