Edgar Rokyan's answer addresses the integral promotion issue in OP's code, but there is another problem reguarding the return value type and the possible overflow of the calculations.
As a matter of fact, considering the example provided in the question, the "product of odd integers from 1 to 15" is 2027025, a value that requires more then 16 bits (the size of an unsigned short
in most systems), so that letting the function return the same type of its parameter would lead to wrong results.
#include <iostream>
#include <type_traits>
#include <stdexcept>
template<typename T>
inline const auto oddProduct(T n) noexcept
-> std::enable_if_t<std::is_unsigned<T>::value, unsigned long long> {
return n < T{2}
? n
: (n % T{2})
? oddProduct<T>(n - T{2})*n
: oddProduct(--n);
}
template<typename T>
inline const auto oddProduct(T n)
-> std::enable_if_t<std::is_signed<T>::value, unsigned long long> {
if ( n < 0 ) throw std::domain_error("Negative value passed");
return n < T{2}
? n
: (n % T{2})
? oddProduct<std::make_unsigned_t<T>>(n - T{2})*n
: oddProduct<std::make_unsigned_t<T>>(--n);
}
int main() {
unsigned char n0 {15};
std::cout << "Product of odd integers from 1 to 15: " << oddProduct(n0) << '\n';
unsigned short n1 {15};
std::cout << "Product of odd integers from 1 to 15: " << oddProduct(n1) << '\n';
unsigned n2 {15};
std::cout << "Product of odd integers from 1 to 15: " << oddProduct(n2) << '\n';
short n3 {15};
std::cout << "Product of odd integers from 1 to 15: " << oddProduct(n3) << '\n';
}
In my proposal, the function always returns an unsigned long long
. I also added an overload to deal with signed types.
std::is_unsigned<T>::value
withstd::is_unsigned_v<T>
. – Baggett