Как я могу использовать либо ‹, либо › (или другой оператор сравнения) в выражении в зависимости от ввода функции?

У меня есть два длинных блока кода, которые идентичны, за исключением различных сравнительных утверждений: > переключается на <, >= на <= и т. д. Я хотел поместить их в функцию и использовать тот или иной оператор в зависимости от ввода функции.

Я пишу на MQL5, но это очень похоже на C++, поэтому, надеюсь, методы, которые работают в этом также будет полезно в моем случае.


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


Ответы (3)


Вы можете создать функцию сравнения для каждого необходимого вам сравнения, а затем передать правильную функцию в качестве аргумента длинным блокам кода (обернутым в соответствующим образом определенную функцию).

В качестве примера рассмотрим следующий гипотетический случай, когда функция (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