签名/未签名的特质编程

xav*_*sjs 3 c++ templates type-traits c++11

我开始学习c ++中的特征和模板.我想知道的是可以为有符号/无符号整数类型创建模板.我们的想法是,可能(可能)为烧结的整数类型实现普通类,以及无符号整数类型的变体.我试过了:

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

template <typename T>
class FXP<unsigned T>
{ ... };
Run Code Online (Sandbox Code Playgroud)

但这不编译.

我甚至遇到过:

std::is_integral

std::is_signed
std::is_unsigned
Run Code Online (Sandbox Code Playgroud)

那么,我如何将它们用于定义仅支持这两种变体的类呢?

小智 8

在这种情况下,有几种方法可以解决它,但我最喜欢的情况是变量数量有限(例如,布尔或两个说它应该表现的方式),模板的部分特化通常是最好的方式去:

// 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
};
Run Code Online (Sandbox Code Playgroud)

您的下一步是提供采用类型名称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
};
Run Code Online (Sandbox Code Playgroud)

在这种情况下,如果您编写默认实现,则只需对非默认情况(如真实情况)进行专门化.

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

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

祝好运!


dyp*_*dyp 5

使用额外的模板参数:

#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-specialized\n"; }
};

template <typename T>
struct FXP< T, typename std::enable_if<std::is_signed<T>{}>::type >
{  void print() { std::cout << "signed\n"; }  };

template <typename T>
struct FXP< T, typename std::enable_if<std::is_unsigned<T>{}>::type >
{  void print() { std::cout << "unsigned\n"; }  };

struct foo {};

int main()
{
    FXP<foo>().print();
    FXP<int>().print();
    FXP<unsigned int>().print();
}
Run Code Online (Sandbox Code Playgroud)