Как мога да използвам ‹ или › (или друг сравнителен оператор) в израз в зависимост от входна функция?

Имам два дълги блока код, които са идентични, освен в различни сравнителни изрази > се превключва с <, >= с <= и т.н. Исках да ги поставя във функция и да използвам един или друг оператор в зависимост от входа на функцията.

Кодирам в MQL5, но това е много подобно на C++, така че се надявам, че методите работят в това ще може да се използва и в моя случай.


person whitebloodcell    schedule 26.04.2014    source източник


Отговори (3)


Можете да създадете функция за сравнение за всяко сравнение, от което се нуждаете, и след това да предадете правилната функция като аргумент към longish кодовите блокове (обвити в подходящо дефинирана функция)

Като пример, разгледайте следния хипотетичен случай, при който функция (myFunc) получава 2 цели числа (a и b) и ги обработва. Стъпките на обработка са подобни, с изключение на типа сравнение, извършено на аргументите. Заобикаляме проблема, като предоставяме на myFunc правилния инструмент за сравнение.

#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;
}

Ясно е, че comp1 и comp2 са двата различни сравнителни елемента. Предаваме един от тях на myFunc в зависимост от изискванията (< или >).

Най-хубавото е, че вашите сравнения вече могат да бъдат толкова сложни, колкото искате, а myFunc не обръща внимание на сложностите.

person axiom    schedule 26.04.2014
comment
Благодаря ви, но за съжаление това изглежда не работи в моята среда. Знаете ли други начини? - person whitebloodcell; 26.04.2014
comment
@whitebloodcell Какви са ограниченията, които карат това да не работи във вашата среда? - person Casper Beyer; 26.04.2014
comment
@whitebloodcell Нямам представа за mql5, но един от начините да го направим може да бъде да направим мозъчна атака и да се уверим, че „дългите блокове код“ са наистина необходими. Може би можете да преструктурирате кода по начин, по който зависимата от оператора част да е минимална. - person axiom; 26.04.2014
comment
Под не работи просто имах предвид, че примерът, който предоставихте, няма да се компилира в моята среда за съжаление. MQL5 е обектно-ориентиран език със синтаксис, много подобен на C++ (цитирам от създателите). Мога да използвам капсулиране и разширяемост на типове, наследяване, полиморфизъм, претоварване и виртуални функции, указатели и т.н., но не и вашето решение за съжаление. - person whitebloodcell; 26.04.2014
comment
Това е валиден C++ код, но за съжаление MQL не поддържа указатели за функциониране - person manlio; 22.05.2014

При кодиране в MQL4 нямате указатели към функция/шаблони. MQL5 има шаблони, но типовете формални параметри са само вградени или основни типове, дефинирани от потребителя .

Можете да опитате нещо като:

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");
}

Не е елегантно, но е ефектно.

person manlio    schedule 22.05.2014

Предайте „компаратор“ като функция или функтор, в този случай използвам std::less и std::greater функтори, дефинирани в functional заглавка, има функтори, дефинирани за повече или по-малко всички оператори.

#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>());
}

Изход:

expression was not true
expression was true
person Casper Beyer    schedule 26.04.2014
comment
В C++ това е валиден подход, но за съжаление MQL5 не поддържа шаблони на класове / формални параметри на сложни шаблони (т.е. функции / функтори). - person manlio; 22.05.2014