测试模板参数的签名性

Testing the signedness of a template parameter

本文关键字:参数 测试      更新时间:2023-10-16

我需要屏蔽一个值的一些前导位。如果这个值是无符号的,我可以断言(保证)没有设置任意数量的前导位,也就是说,这个值保证是有限的。

如果它是签名的,我需要屏蔽前导位(将值变成一些不可移植的位堆,是的,我知道:-))。如果值是无符号的,我想保存屏蔽操作。

所以我基本上有

template<typename T, some more template parameters>
class {
    unsigned transform(T value) {
        ...
        if (isSigned(T)) {
            value &= mask;
        }
        ...
    }
}

有没有一种简单的方法可以编写isSigned(),它可以在编译时进行评估(使优化器能够删除未签名的死代码)?

当然,我可以添加另一个模板参数。。。

是。你必须使用部分专业化:

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特性类,而不是滚动自己的特性类。

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); }

使用limits标头中的numeric_limits

if(numeric_limits<T>::is_signed) { … }

正如Kerrek所说,我会选择部分专业化。否则,编译器可能会抱怨条件的值在编译时是已知的。