【问题标题】:Template specialization for float浮动的模板特化
【发布时间】:2016-03-15 09:59:32
【问题描述】:

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

我的限制类得到一个类型以及最小值和最大值。要将 Limit 用于 int 和 float,我目前使用的是:

template <typename U, typename T = U, T A1 = 0, T A2 = 0, T A3 = 0, T A4 = 0>
struct Limit {
  static constexpr const U min = A1;
  static constexpr const U max = A2;
};

template <intmax_t A1, intmax_t A2, intmax_t A3, intmax_t A4>
struct Limit<float, intmax_t, A1, A2, A3, A4>  {
  static constexpr const float min = A1 / (float) A2;
  static constexpr const float max = A3 / (float) A4;
};

Limit<float, intmax_t, 40, 20, 30, 40> a;

Limit<int, 10, 20> b;

有没有办法优化这个实现?并且也许启用浮动实现的默认值?

提前谢谢你!

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

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

【问题讨论】:

  • 有关这些值范围的一些信息可能会有所帮助。您的另一个选择是通过使用指数而不是分母来“模拟”浮点数 - 两个限制可能相同(因此请求范围)
  • 您当前的代码无法编译 (g++ 5.3.0),因为 Limit&lt;int, 10, 20&gt; 不是有效的实例化(第二个参数必须是类型)。如果您使用这种方法,您将不得不创建另一个专业化。
  • 定义“优化”。
  • 定义“不工作”。

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


【解决方案1】:

您的实现我认为使用std::ratio 非常令人兴奋。您可以为您的minmax 使用两个原始std::ratio 或类似以下的一些实现:

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

【讨论】:

  • 谢谢。 std::ratio 是一个选项,但如果我有 Num 和 Denom,我认为不需要定义额外的比率。 .... 对于 int 值,我必须定义:Limit,请参阅我的更新。
【解决方案2】:

您可以始终将其包装在 ratios 中,这样您就可以写成 Limit&lt;int, std:::ratio&lt;100&gt;, std::ratio&lt;200&gt;&gt;...

或者你可以按照以下方式做一些事情

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2022-07-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-02-19
    • 2019-08-23
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多