I’m trying to implement a function which accepts only unsigned integral types. Below is what I’ve tried so far. It works for "unsigned int", but why doesn’t this compile for an "unsigned short?"
#include <iostream>
#include <type_traits>
template<typename T, class = typename std::enable_if<std::is_unsigned<T>::value>::type>
inline const T oddProduct(T n) noexcept {
return (n <= 1) ? n : (n % 2) ? oddProduct(n - 2)*n : oddProduct(--n);
}
int main() {
std::cout << "Product of odd integers from 1 to 15: " << oddProduct<unsigned short>(15) << std::endl;
return 0;
}
Note: MSVS 2017 Community C++14 options.
The thing is that due to the integral promotion:
n - 2
has a type of int
which is not unsigned
.
You might try to add static_cast
:
template<typename T, class = typename std::enable_if<std::is_unsigned<T>::value>::type>
inline const T oddProduct(T n) noexcept {
return (n <= 1) ? n : (n % 2) ? oddProduct(static_cast<T>(n - 2))*n : oddProduct(--n);
^^^^^^^^^^^^^^
}
so n - 2
is casted to unsigned short
when you call oddProduct<unsigned short>
.
Another possible option is to change 2
to 2U
.
Also note, that, once you use C++14, you might use std::enable_if_t
:
class = typename std::enable_if_t<std::is_unsigned<T>::value>