我需要屏蔽一些值的前导位。如果该值是无符号的,我可以断言(保证)没有设置任意数量的前导位,即保证该值是有限的。
如果签名,我需要屏蔽掉前导位(将值转换为一些不可移植的位堆,是的,我知道:-))。如果值是无符号的,我想保存屏蔽操作。
所以我基本上有
template<typename T, some more template parameters>
class {
unsigned transform(T value) {
...
if (isSigned(T)) {
value &= mask;
}
...
}
}
是否有一种简单的方法可以编写一个isSigned(),它可以在编译时进行评估(以使优化器能够删除未签名的死代码)?
当然我可以添加另一个模板参数......
答案 0 :(得分:5)
是。你必须使用部分专业化:
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>();
// ...
}
};
您可以使用<type_traits>
中现成的is_signed
特质类,而不是自己编辑。
答案 1 :(得分:3)
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); }
答案 2 :(得分:2)
使用numeric_limits
标题中的limits
:
if(numeric_limits<T>::is_signed) { … }
像克雷克说的那样,我会选择部分专业化。否则,编译器可能会抱怨条件的值在编译时是已知的。