How can I use either < or > (or other comparative operator) in an expression depending on a function input?

StackOverflow https://stackoverflow.com/questions/23310665

Domanda

I have two longish blocks of code that are identical except in various comparative statements > is switched with <, >= with <= etc. I wanted to put these in a function and use one operator or another depending on a function input.

I am coding in MQL5 but this is very similar to C++ so hopefully methods that work in this will also be useable in my case.

È stato utile?

Soluzione

You can create a comparator function for each comparison you need, and then pass the right function as an argument to the longish code blocks (wrapped in a suitably defined function)

As an example, consider the following hypothetical case where a function (myFunc) receives 2 integers(a and b) and processes them. The processing steps are similar except for the type of comparison done on the arguments. We get around the problem by providing myFunc with the right tool for comparison.

#include <iostream>
using namespace std;

bool comp1(int a, int b) {
    return a > b;
}

bool comp2(int a, int b) {
    return a < b;
}

void myFunc(int a, int b, bool (*myComp)(int, int)) {
    bool res = myComp(a, b);
    cout << "value : " << res << endl;
}
int main()
{
    myFunc(1, 2, comp1); //use >
    myFunc(1, 2, comp2); //use <
    return 0;
}

Clearly, comp1 and comp2 are the 2 different comparators. We pass one of them to myFunc depending on the requirements (< or >).

The best thing is that your comparisons can now be as complex as you want, and myFunc is oblivious to the complexities.

Altri suggerimenti

Coding in MQL4 you haven't pointers to function / templates. MQL5 has templates but formal parameter types are only built-in or basic user-defined types.

You could try something like:

enum COMPARATOR
{
  C_EQUAL = 0,
  C_LESS = 1,
  C_GREATER = -1
  C_AT_MOST = 2,
  C_AT_LEAST = -2,
};

bool cmp(int a, int b, COMPARATOR c)
{
  switch (c)
  {
  case C_LESS:     return a < b;
  case C_AT_MOST:  return a <= b;
  case C_EQUAL:    return a == b;
  case C_AT_LEAST: return a >= b;
  case C_GREATER:  return a > b;
  }

  Alert("INTERNAL ERROR: UNKNOWN COMPARISON");
  return false;
}

void a_function(COMPARATOR c)
{
  if (cmp(MathRand(), 13, c))
    Print("BOOM");

  // *** If you need the "opposite" of c *** you can write:
  if (cmp(Time[0], Time[1], COMPARATOR(-c))
    Alert("DONE");
}

It isn't elegant but it's effective.

Pass in a "comparator" as a function or functor, in this case I'm using the std::less and std::greater functors defined in the functional header, there are functors defined for more or less all the operators.

#include <iostream>
#include <functional>

template<typename Comparator>
void do_something(Comparator comp)
{
   int a = 1;
   int b = 2;

   if (comp(a, b)) {
      std::cout << "expression was true" << std::endl;
   } else {
      std::cout << "expression was not true" << std::endl;
   }
}

int main(int argc, char* argv[])
{
   do_something(std::greater<int>());
   do_something(std::less<int>());
}

Output:

expression was not true
expression was true
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top