C++:`enable_if` 限制支持特定算术运算的类型
C++: `enable_if` to restrict types that support specific arithmetic operations
我想定义只能应用于支持乘法的类型的模板函数,例如int
、long
、float
以及带有重载运算符的自定义类型,例如 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) {
// ...
}
如果只需要测试,如果一个类型可以自相乘,可以使用:
template <class T,
class = decltype(std::declval<T>() * std::declval<T>())>
T power (T base, unsigned int exponent) {
...
}
查看 fundamentals TS v2 中的 is_detected
(还提供了可能的实现)。如果您想对各种操作进行频繁检查,这为您提供了良好的基础。它基本上允许您检查给定类型上是否可以进行指定操作。
首先,您定义操作类型:
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
的条件:
template <typename T, typename = std::enable_if_t<can_multiply<T, unsigned int>>
T power (T base, unsigned int exponent) {
// ...
}
这也增加了一些可读性(至少在我看来),因为 can_multiply
清楚地表达了您的意图。
Here 是一个完整的实施示例。
Another 包含更多操作的示例。
我想定义只能应用于支持乘法的类型的模板函数,例如int
、long
、float
以及带有重载运算符的自定义类型,例如 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) {
// ...
}
如果只需要测试,如果一个类型可以自相乘,可以使用:
template <class T,
class = decltype(std::declval<T>() * std::declval<T>())>
T power (T base, unsigned int exponent) {
...
}
查看 fundamentals TS v2 中的 is_detected
(还提供了可能的实现)。如果您想对各种操作进行频繁检查,这为您提供了良好的基础。它基本上允许您检查给定类型上是否可以进行指定操作。
首先,您定义操作类型:
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
的条件:
template <typename T, typename = std::enable_if_t<can_multiply<T, unsigned int>>
T power (T base, unsigned int exponent) {
// ...
}
这也增加了一些可读性(至少在我看来),因为 can_multiply
清楚地表达了您的意图。
Here 是一个完整的实施示例。
Another 包含更多操作的示例。