9

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.)

Community
  • 1
  • 1
Damon
  • 67,688
  • 20
  • 135
  • 185

1 Answers1

10

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;
bames53
  • 86,085
  • 15
  • 179
  • 244
  • I'm facing a similar issue for C++03. I want two templates: one for `template ` and class `template `. I need to test if a cast can be made from `T` to `U`. Is there a solution in the C++03 world? (Does this warrant a new question)? – jww Jul 29 '15 at 12:42
  • 1
    @jww yeah, I'd say that should be its own question. – bames53 Jul 29 '15 at 20:08