Take a look at is_detected
from fundamentals TS v2 (there is also a possible implementation provided). This provides you with a good base in case you want to do frequent checks on various operations. It basically allows you to check if a specified operation is possible on the given types.
First, you define your operation type:
template <typename Lhs, typename Rhs>
using multiplication_t = decltype(std::declval<Lhs>() * std::declval<Rhs>());
then you make a type trait out of it:
template <typename Lhs, typename Rhs>
constexpr bool can_multiply = is_detected<multiplication_t, Lhs, Rhs>::value;
You can now use the trait as a condition for enabled_if
:
template <typename T, typename = std::enable_if_t<can_multiply<T, unsigned int>>
T power (T base, unsigned int exponent) {
// ...
}
This also adds some readability (imo at least), cause can_multiply
clearly expresses your intention.
Here is a full implementation as example.
Another example with more operations.