Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/templates/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 测试模板参数的符号性_C++_Templates - Fatal编程技术网

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
,所以我将再次使用它。