C ++:`enable_if`来限制支持特定算术运算的类型

时间:2019-06-03 21:40:04

标签: c++ sfinae

我想定义仅可用于支持乘法的类型的模板函数,例如intlongfloat和带有重载运算符的自定义类型,例如Martix

class Matrix {
    public:
        Matrix operator*(const Matrix& other) const;
}

是否可以通过这种方式限制模板类型?

template <typename T, typename = std::enable_if_t< /* multiplication is defined */ >>
T power (T base, unsigned int exponent) {
    // ...
}

2 个答案:

答案 0 :(得分:6)

如果只需要测试,如果类型可以自身相乘,则可以使用:

template <class T, 
          class = decltype(std::declval<T>() * std::declval<T>())>
T power (T base, unsigned int exponent) {
     ...
}

答案 1 :(得分:3)

看看基础TS v2 中的is_detected(也提供了可能的实现方式)。如果您想经常检查各种操作,这为您提供了良好的基础。基本上,它使您可以检查是否可以对给定类型执行指定的操作。

首先,您定义您的操作类型:

Int

然后使用它来制作类型特征:

template <typename Lhs, typename Rhs>
using multiplication_t = decltype(std::declval<Lhs>() * std::declval<Rhs>());

您现在可以将特征用作template <typename Lhs, typename Rhs> constexpr bool can_multiply = is_detected<multiplication_t, Lhs, Rhs>::value; 的条件:

enabled_if

这也增加了一些可读性(至少是imo),因为template <typename T, typename = std::enable_if_t<can_multiply<T, unsigned int>> T power (T base, unsigned int exponent) { // ... } 清楚地表达了您的意图。

Here是完整的示例。

Another示例,其中包含更多操作。