Ищу в кодобазе интересные варианты применения typedef

 

Перенесено:

fxsaber:

Ищу в кодобазе интересные варианты применения typedef. Не нашел. CopyTicks - аналогично.

Дайте ссылки, если знаете. 

 

typedef не применял никогда. Поэтому и ищу. Об этом сразу задумался, когда понадобилось массив объектов отсортировать по какому-то условию.

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

Поскольку функции сравнения могут быть хитрыми, то входной параметр должен быть либо void*, либо через template. typеdef же будет отвечать как раз за создание функции сравнения.

Пока сумбурно, т.к. ни строчки не написал еще.

 

В справке про typedef ни слова! 

 
Гадина не работает даже в простом случае
template <typename T>
typedef bool (*COMPARE)( const T&, const T& ); // не фига не работает!

#define DEFINE_COMPARE(A, B)                            \
  template <typename T>                                 \
  bool Compare##A( const T &Object1, const T &Object2 ) \
  { return(Object.volume B Object.volume); }

DEFINE_COMPARE(1, >)
DEFINE_COMPARE(2, <)

template <typename T>
int ArrayCondition( const T &Array[], COMPARE<T> Compare ) // не фига не работает!
{
  int Res = 0;
  
  const int Amount = ArraySize(Array);
  
  for (int i = 1; i < Amount; i++)
    if (Compare(Array[i], Array[i - 1]))
      Res++;
      
  return(Res);
}

void OnStart( void )
{
  MqlTick Ticks[];
  
  CopyTicks(_Symbol, Ticks);
  
  Print(ArrayCondition(Ticks, Compare1));
  Print(ArrayCondition(Ticks, Compare2));

  MqlBookInfo Books[];

  Print(ArrayCondition(Books, Compare1));
  Print(ArrayCondition(Books, Compare2));
}
Как надо-то? Документации ноль!
 
fxsaber:
Гадина не работает даже в простом случаеКак надо-то? Документации ноль!

а разве в MQL появились указатели или ссылки на функции ?

я как-то обходил отсутсвие call-back`ов заворачивая функцию в класс. Кривенько, но работает :-) Что-то типа такого :

class Comparator {

public:

  int compare(void *,void *);

}

 
Maxim Kuznetsov:

а разве в MQL появились указатели или ссылки на функции ?

Типа, да.

я как-то обходил отсутсвие call-back`ов заворачивая функцию в класс. Кривенько, но работает :-) Что-то типа такого :

class Comparator {

public:

  int compare(void *,void *);

}

Рабочий кусочек, пожалуйста!
 
fxsaber:

Типа, да.

Рабочий кусочек, пожалуйста!
//+------------------------------------------------------------------+
//|                                                     CallBack.mq4 |
//|                                                Maxim A.Kuznetsov |
//|                                                       nektomk.ru |
//+------------------------------------------------------------------+
#property copyright "Maxim A.Kuznetsov"
#property link      "nektomk.ru"
#property version   "1.00"
#property strict

class Func {
public:
   virtual double run(double _x) { return _x; }
};
class Add: public Func {
public:
   double y;
   Add(double _y=1) { y=_y;};
   double run(double _x) { return _x + y; };
};
class Mult: public Func {
public:
   double y;
   Mult(double _y=2) { y=_y;};
   double run(double _x) { return _x * y; };
};
class Sum: public Func {
public:
   double acc;
   Sum(double _acc=0) { acc=_acc;};
   double run(double _x) { return (acc=_x+acc); };
};
void Map(const double &src[],double &dst[],Func &f) {
   int pos,size;
   size=ArraySize(src);
   ArrayResize(dst,size);
   for(pos=0;pos<size;pos++) {
      dst[pos]=f.run(src[pos]);
   }
}
string PrintArray(string name,const double &arr[],int digits=5) {
   string s;
   int size,pos;
   size=ArraySize(arr);
   s=StringFormat("%s[%d]={",name,size);
   for(pos=0;pos<size;pos++) {
      if (pos!=0) s+=",";
      s+=DoubleToString(arr[pos],digits);
   }
   s+="}";
   Print(s);
   return s;
}
void OnStart()
{
   double src[5]={1,2,3,4,5};
   double dst[];
   int t;
   Func *func[4];
   func[0]=new Func;
   func[1]=new Add(2);
   func[2]=new Mult(3);
   func[3]=new Sum;
   for(t=ArraySize(func)-1;t>=0;t--) {
      Map(src,dst,func[t]); PrintArray(IntegerToString(t)+" dst",dst);
      delete func[t];
   }
}


 
Maxim Kuznetsov:
Спасибо, но я был заинтригован void*. В примере этого нет.
 
C/С++: typedef никогда не работал с шаблонами (только через шаблон структуры/класса). В С++11 появился альтернативный способ создавать псевдонимы -  через using, вот он допускает использование шаблонов.
template <typename _T> using fp = void(*)(_T);
void f(fp<int> arg){}

Но ждать чудес от мкл при работе с typedef не стоит, тем более наличие using. Пытался немного поколдовать над вашим кодом - не работают элементарные конструкции вида:

#define DEFINE_COMPARE(A, B)                                    \
template <typename T>                                           \
struct Compare##A{                                              \
  typedef T type;                 /*Выдаёт ошибку*/             \
  static bool compare( const T &Object1, const T &Object2 ){    \
    return(Object1.volume B Object2.volume);                    \
  }                                                             \
};
А ещё вызвать функцию с указанием типа fn<int>(); В общем, написать можно, но как-то на костылях всё.
 
pavlick_:
C/С++: typedef никогда не работал с шаблонами. В С++11 появился альтернативный способ создавать псевдонимы -  через using, вот он допускает использование шаблонов.

Но ждать чудес от мкл при работе с typedef не стоит, тем более наличие using. Пытался немного поколдовать над вашим кодом - не работают элементарные конструкции вида:

А ещё вызвать функцию с указанием типа fn<int>(); В общем, написать можно, но как-то на костылях всё.
Спасибо. Удивило, что хотелки даже C++ на колени поставили.
 
Maxim Kuznetsov:

а разве в MQL появились указатели или ссылки на функции ?

я как-то обходил отсутсвие call-back`ов заворачивая функцию в класс. Кривенько, но работает :-) Что-то типа такого :

Совсем даже не кривенько - это нормальный рабочий паттерн. А вот с навороченными дифайнами заморочишься ошибки разбирать, если они потом (не сразу) возникнут.
Причина обращения: