1
votes

I would like to implement a template function that compares two variables of two types (T1 and T2). These types are two random unsigned or signed integer types.

To be able to compare them correctly I need to cast both of them to a 'bigger' integer type (T3). Promotion rules for signed/unsigned comparison unfortunately always promote to the unsigned type.

So how can I find a type T3 in C++11/C++14/C++17 that covers two integer types T1 and T2, no matter which size and signedness they have? If this isn't possible, is there an other solution to build a template based comparison function that works reliably with any integer combination?

2
This approach will not work for the largest type, i.e. if T1 is the largest signed type and T2 is its unsigned counterpart. - AnT
What do you mean by compare? Absolute value? - Escualo
@Escualo: Your code is what I want to do. But without overloading. I would need code that gives me a T3 that can contain T1 and T2 without loss of precision. common_type does not do that. - Silicomancer

2 Answers

2
votes

You can split the comparison up into parts. First check if one number is negative, and the other positive. If that's the case you know what order they go in. If neither is negative (or both are), just do a normal comparison.

This can be built in a template function that'll only check for negative of signed types.

0
votes

I am not sure I understand your question. Do you mean something like this:

#include <cstdint>
#include <type_traits>

template < typename P, typename Q >
auto
compare( P p, Q q ) {
  using T = typename std::common_type< P, Q >::type;
  T promoted_p{p};
  T promoted_q{q};

  if ( promoted_p < promoted_q ) {
    return -1;
  }
  else if ( promoted_p > promoted_q ) {
    return 1;
  }
  else {
    return 0;
  }
}

It will work when safe to do so, and you can add your specializations if the language is not doing what you want.