我想定义仅可用于支持乘法的类型的模板函数,例如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) {
// ...
}
答案 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示例,其中包含更多操作。