有符号/无符号特质编程

4

我开始学习 C++ 中的 traits 和 templates。 我想知道是否可以为有符号/无符号整数类型创建模板。 这个想法是普通类可能会为有符号整数类型实现,而变体为无符号整数类型实现。 我尝试过:

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

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

但是这段代码无法编译。

我甚至遇到了以下问题:

std::is_integral

std::is_signed
std::is_unsigned

那么,我该如何将它们付诸实践以定义一个仅支持这两种变体的类呢?
2个回答

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
};

你的下一步是提供一个针对指定模板参数的特化版本,该版本采用typename 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
};

在这种情况下,如果您编写默认实现,您只需要为非默认情况(如true情况)进行专门化。
以下是一个示例,其中默认情况被专门的模板参数覆盖:http://coliru.stacked-crooked.com/a/bc761b7b44b0d452
请注意,这仅适用于较小的情况。如果您需要复杂的测试,则最好使用std::enable_if和一些更复杂的模板参数(如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();
}

这是一种更通用的变体,支持超过两个选项。 - dyp

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接