浮动的模板专业化

时间:2016-03-15 09:59:33

标签: c++ templates c++11 template-specialization

我知道,我不能在模板中使用float作为非类型参数。所以我想用限制类的分子和分母。

我的限制类获取类型以及最小值和最大值。要使用Limit for int和float我现在使用:

// For int, char, short, uint32_t etc...
template <typename U, U MIN, U MAX>
struct Limit {
  static constexpr const U min = MIN;
  static constexpr const U max = MAX;
};

// For float/double
template <typename T /*float or double*/, typename MIN, typename MAX>
struct Limit  {
  static constexpr const T min = MIN.num / (T) MIN.dem; // static cast...
  static constexpr const T max = MAX.num / (T) MAX.dem; // static cast...
};

Limit<int, int, 10, 20> a;

Limit<float, std::ratio<4,5>, std::ratio<10,15>> b;

有没有办法优化此实现?也许为float实现启用默认值?

提前谢谢!

编辑:我想要一个像这样的模板声明(不工作):

nasm -f elf64 hello.S -o hello.o

2 个答案:

答案 0 :(得分:4)

您的实施我认为使用std::ratio会感到尖叫。您可以为std::ratiomin使用两个原始max或下面的某些实现:

template<typename U, std::intmax_t NumerMin = 0, std::intmax_t DenomMin = 1,
                     std::intmax_t NumerMax = 0, std::intmax_t DenomMax = 1>
struct Limit {
  static const std::ratio<NumerMin, DenomMin> min_;
  static const std::ratio<NumerMax, DenomMax> max_;
public:
  U const min = static_cast<U>(min_.num) / static_cast<U>(min_.den);
  U const max = static_cast<U>(max_.num) / static_cast<U>(max_.den);
};

Live Demo

答案 1 :(得分:1)

您可以始终将其打包在ratio中,以便您撰写Limit<int, std:::ratio<100>, std::ratio<200>> ...

或者你可以按照

的方式做点什么
// if T is floating point, return std::intmax_t, otherwise T.
template<class T>
using adjust_floating = std::conditional_t<std::is_floating_point<T>{}, std::intmax_t, T>;

template <class T, adjust_floating<T> A1 = 0,
                   adjust_floating<T> A2 = 0,
                   adjust_floating<T> A3 = 0,
                   adjust_floating<T> A4 = 0 >
struct Limit {
    // maybe static_assert that A3 and A4 are zero if T isn't floating point
    static constexpr T min = std::is_floating_point<T>{} ? A1 / (T) A2 : A1;
    static constexpr T max = std::is_floating_point<T>{} ? A3 / (T) A4 : A2;
};