I can use templates and delete facility to prevent calling factorial with character or float variables as follows. How to write the delete function for factorials with negative arguments?
template <typename T>
constexpr T factorial(T n)
{
return (n == 1 || n == 0) ? 1 : (n * factorial(n - 1));
}
constexpr float factorial(double) = delete;
constexpr char factorial(char) = delete;
int main()
{
constexpr auto fiveFactorial = factorial(5);
constexpr auto point5fact = factorial(0.5); // Error. Call to deleted version
constexpr auto letter5fact = factorial('5'); // DITTO
constexpr auto minusFact = factorial(-1); // How to prevent this using delete?
}
Impossible. = delete
is a compile-time thing, while your arguments aren't always known at compile-time.
You could use unsigned
parameter instead and remove all those deleted overloads, at the cost of being unable to call your function with signed numbers, like factorial(2)
.
template <typename T> constexpr T factorial(T n)
{
static_assert(std::is_unsigned_v<T> && !std::is_same_v<T, char>,
"Parameter type must be integral, unsigned, and not `char`.");
return (n == 1 || n == 0) ? 1 : (n * factorial(T(n - 1)));
}