有符号/无符号特征编程



我开始学习c++中的特性和模板。我想知道的是,是否可以为有符号/无符号积分类型创建模板。其思想是,普通类(可能)将针对单值整数类型实现,而变体则针对无符号整数类型实现。我试过了:

template <typename T>
class FXP<T>
{ ... };
template <typename T>
class FXP<unsigned T>
{ ... };

但这不会编译。

我甚至遇到了:

std::is_integral
std::is_signed
std::is_unsigned

那么,我该如何将这些应用于定义一个只支持这两种变体的类呢?

在这种情况下,有几种方法可以实现,但我最喜欢的是在变体数量有限的情况下(例如,一个或两个布尔值表示它应该以何种方式表现),模板的部分专业化通常是最好的方法:

// Original implementation with default boolean for the variation type
template <typename T, bool is_unsigned = std::is_unsigned<T>::value>
class FXP {
     // default implementation here
};

然后,您的下一步是提供一个部分专用化,它采用类型名T,但仅适用于模板参数的特定变体(例如truefalse)。

template <typename T>
class FXP<T, false> {
     // partial specialization when is_unsigned becomes false
};
template <typename T>
class FXP<T, true> {
     // partial specialization when is_unsigned becomes true
};

在这种情况下,如果您编写了一个默认实现,您只需要为非默认情况(如真实情况)进行专门化。

下面是一个示例,其中默认情况被一个专门的模板参数覆盖:http://coliru.stacked-crooked.com/a/bc761b7b44b0d452

请注意,这只适用于较小的情况。如果你需要复杂的测试,最好使用std::enable_If和一些更复杂的模板参数(比如DyP的答案)。

祝你好运!

带有额外的模板参数:

#include <iostream>
#include <type_traits>
template <typename T, class X = void>
struct FXP
{
    // possibly disallow using this primary template:
    // static_assert(not std::is_same<X, X>{},
    //               "Error: type neither signed nor unsigned");
    void print() { std::cout << "non-specializedn"; }
};
template <typename T>
struct FXP< T, typename std::enable_if<std::is_signed<T>{}>::type >
{  void print() { std::cout << "signedn"; }  };
template <typename T>
struct FXP< T, typename std::enable_if<std::is_unsigned<T>{}>::type >
{  void print() { std::cout << "unsignedn"; }  };
struct foo {};
int main()
{
    FXP<foo>().print();
    FXP<int>().print();
    FXP<unsigned int>().print();
}

最新更新