测试模板参数的签名

时间:2012-03-15 23:41:39

标签: c++ templates

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

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

所以我基本上有

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

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

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

3 个答案:

答案 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) { … }
像克雷克说的那样,我会选择部分专业化。否则,编译器可能会抱怨条件的值在编译时是已知的。