Search code examples
c++templatesmathfunctorrelational-operators

Can I Write Relational Operators in Terms of Arithmetic Operations?


So I have a fairly complex function:

template <typename T>
void foo(const int param1, const int param2, int& out_param)

Given int bar, const int arg1, and const int arg2 the function will be called with either: foo<plus<int>>(arg1, arg2, bar) or foo<minus<int>>(arg1, arg2, bar)

Internally the function is rather complex but I am doing different relational operators based on the type of functor that was passed as a template parameter.

In the case of plus I need to do:

  1. arg1 > arg2
  2. bar > 0
  3. bar > -10

In the case of minus I need to do:

  1. arg1 < arg2
  2. bar < 0
  3. bar < 10

Note that 10 does not have the same sign in both 3s. I am currently solving all this by passing a second template parameter (less or greater.) But I was thinking it might make more sense to write these relations as arithmetic operations. Is that even possible, or do I need to take the second template parameter?


Solution

  • T{}(0, arg1) > T{}(0,arg2);
    T{}(0, bar) > 0;
    T{}(0, bar) > -10;
    

    The basic idea is a > b if and only if -a < -b. And plus(0,a)==a while minus(0,a)==-a.

    The last one is tricky, as we want to change the order of < and the sign. Luckily they cancel:

    Suppose we want a constant that is -10 in the plus case, and 10 in the minus case. Then

    plus(0,-10)
    

    is -10 and

    minus(0,-10)
    

    is 10.

    So we get:

    T{}(0, bar) > T{}(0, T{}(0,-10))
    

    in the plus case, the rhs is 0+0+-10, aka -10.

    In the minus case, this is 0-(0-(-10)), aka -10.

    So the short form is:

    T{}(0,bar) > -10
    

    and it should work.