C++ 测试模板参数的符号性
我需要屏蔽一个值的一些前导位。如果该值是无符号的,我可以断言(保证)未设置任意数量的前导位,即该值保证是有限的 如果它是有符号的,我需要屏蔽前导位(将值转换为一些不可移植的位堆,是的,我知道:-))。如果值未签名,我想保存屏蔽操作 所以我基本上有C++ 测试模板参数的符号性,c++,templates,C++,Templates,我需要屏蔽一个值的一些前导位。如果该值是无符号的,我可以断言(保证)未设置任意数量的前导位,即该值保证是有限的 如果它是有符号的,我需要屏蔽前导位(将值转换为一些不可移植的位堆,是的,我知道:-))。如果值未签名,我想保存屏蔽操作 所以我基本上有 template<typename T, some more template parameters> class { unsigned transform(T value) { ... if (is
template<typename T, some more template parameters>
class {
unsigned transform(T value) {
...
if (isSigned(T)) {
value &= mask;
}
...
}
}
模板
阶级{
无符号变换(T值){
...
如果(未签名(T)){
值&=掩码;
}
...
}
}
是否有一种简单的方法可以编写isSigned()并在编译时进行计算(以使优化器能够删除未签名的死代码)
当然,我可以添加另一个模板参数…如果(T(-1)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); }
模板
内联void apply_mask_helper(T&value){value&=mask;}
模板
内联void apply_mask_helper(T&){
模板
内联void apply_mask(T&value){apply_mask_helper(value);}
是。您必须使用部分专业:
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>();
// ...
}
};
template struct impl{static void foo();};
模板结构impl{static void foo();};
模板结构Foo
{
void do_magic(T常数&)
{
impl();
// ...
}
};
您可以使用
中现成的trait类,而不是滚动自己的trait类。使用限制
标题中的数值限制
:
if(numeric_limits<T>::is_signed) { … }
if(数字限制::有符号){…}
正如克里所说,我会选择部分专业化。否则,编译器可能会抱怨编译时已知条件值。实际上,编译器完全能够优化死代码。但它可能会发出警告…@KonradRudolph:这是一个细节。OP可能希望编写的代码仅在两种情况中的一种情况下有意义,而
if
语句要求您编写正确的代码,即使从未使用过。模板没有这个限制。谢谢,我会去的。缺少的主要内容是std::is_signed
(或者numeric_limits::is_signed
或者甚至T(-1)
:-)您还可以创建一个重载,该重载有一个额外的std::true_类型
和另一个额外的std::false_类型
参数,并传递typename std::is_signed::type()
作为该参数。然后它将适当地调用已签名或未签名的版本。有符号性不是一个很好的例子,当不尝试将参数视为一个数字时,std::is_integral
是一个更好的用例。我认为OP已经有一个编译时有符号性检查,只是想要一个条件的静态版本…我将继续,并查看生成的代码,通常gcc处理得很好:-)@Kerrek是静态条件吗?好吧,这只适用于三元运算符,因为只有在运行时才计算。@drhirsch:静态条件是我在回答中写的。它是在编译时解析的条件。C++没有内置的“<代码>静态I/Eng/>”,所以我们有这个模板拐杖。事实上,现在我认识到我已经在代码的其他部分使用了专门化作为静态if
,所以我将再次使用它。