Reputation: 70126
In a template function that looks like this:
template<typename T> constexpr T foo(T a, T b) { return /*recursive call*/; }
I am getting a warning about comparing signed vs unsigned (due to comparing against sizeof
) which I'd like to eliminate.
Conceptually, one would need something like this:
template<typename T> constexpr T foo(T a, unsigned T b) { ... }
or
template<typename T> constexpr T foo(T a, std::make_unsigned<T>::type b) { ... }
Unluckily, the first version is not valid C++, and the second version breaks the build because T is not a qualified type when the compiler sees make_unsigned
.
Is there is a solution for this that actually works?
(NB: Somehow related to / almost same as Get the signed/unsigned variant of an integer template parameter without explicit traits, though function rather than class (so no typedefs), traits or any feature of C++11 explicitly welcome, and working solution (i.e. not make_unsigned<T>
) preferred.)
Upvotes: 9
Views: 2125
Reputation: 88155
You forgot a 'typename'
template<typename T>
constexpr T foo(T a, typename std::make_unsigned<T>::type b) { ... }
In C++14 you should be able to write
template<typename T>
constexpr T foo(T a, std::make_unsigned_t<T> b) { ... }
Or you can implement this yourself in C++11:
template<typename T>
using make_unsigned_t = typename std::make_unsigned<T>::type;
Upvotes: 10