Download MetaTrader 5
To add comments, please log in or register
Store your source codes in MQL5 Storage. It is secure!
Amy Liu
640
Amy Liu 2014.11.14 13:20 

It's said in MQL4 Reference that "Function templates can also be used for class methods". Then I tried th folwing code:

class CTest
  {
private:
   
public:
                     
                     CTest();
                    ~CTest();
                    template<typename T>
                    void Func(T &data);
  };
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
CTest::CTest()
  {typename
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
CTest::~CTest()
  {
  }
//+------------------------------------------------------------------+


CTest::Func(T &data)
{
}

Compiler says: template functions overloading is not supported yet...

Does anybody successfully do template functions in a class? 

Sergey Dzyublik
4652
Sergey Dzyublik 2014.11.14 14:20  
lob32371 12.11.2014 19:35 #

Сделал симуляцию указателей на функцию. Sort.mqh:

#property strict

class SORT
{
private:
  template <typename T>
  static void Swap( T &Array[], const int i, const int j )
  {
    const T Temp = Array[i];

    Array[i] = Array[j];
    Array[j] = Temp;

    return;
  }

  template<typename T1, typename T2>
  static int Partition( T1 &Array[], const T2 &Compare, const int Start, const int End )
  {
    int Marker = Start;

    for (int i = Start; i <= End; i++)
      if (Compare.Compare(Array[i], Array[End]) <= 0)
      {
        Swap(Array, i, Marker);

        Marker++;
      }

     return(Marker - 1);
  }

  template<typename T1, typename T2>
  static void QuickSort( T1 &Array[], const T2 &Compare, const int Start, const int End )
  {
    if (Start < End)
    {
      const int Pivot = Partition(Array, Compare, Start, End);

      QuickSort(Array, Compare, Start, Pivot - 1);
      QuickSort(Array, Compare, Pivot + 1, End);
    }

    return;
  }

public:
  /* синтаксис почти соответствует MQL-штатной ArraySort:
       void&       array[]                   // массив для сортировки
       void&       Compare                   // условие сортировки (с направлением)
       int         count = WHOLE_ARRAY,      // количество элементов
       int         start = 0,                // начальный индекс
  */
  template<typename T1, typename T2>
  static void Sort( T1 &Array[], const T2 Compare, int Count = WHOLE_ARRAY, const int Start = 0 )
  {
    if (Count == WHOLE_ARRAY)
      Count = ArraySize(Array);

    if (CheckPointer(Compare) != POINTER_INVALID)
      QuickSort(Array, Compare, Start, Start + Count - 1);

    if (CheckPointer(Compare) == POINTER_DYNAMIC)
      delete Compare;

    return;
  }
};

class COMPARE
{
private:
  const int Mode;

protected:
  template <typename T>
  T SetMode( T Value ) const
  {
    if (Mode != MODE_ASCEND)
      Value = -Value;

    return(Value);
  }

public:
  COMPARE( const int iMode = MODE_ASCEND ): Mode(iMode)
  {
  }

  template<typename T>
  T Compare( const T First, const T Second ) const
  {
    return(SetMode(First - Second));
  }
};

Вот так теперь можно делать кастомную сортировку массивов из любых объектов:

#property strict

#include <Sort.mqh>

template <typename T>
void PrintArray( const T &Array[] )
{
  const int Size = ArraySize(Array);
  string Str = "";

  for (int i = 0; i < Size; i++)
    Str = Str + " " + (string)Array[i];

  Print(Str);
}

class CompareByAbs : public COMPARE
{
public:
  template<typename T>
  T Compare( const T First, const T Second ) const
  {
    return(SetMode(
           MathAbs(First) - MathAbs(Second) // условие сортировки
           ));
  }

  CompareByAbs( const int iMode = MODE_ASCEND ) : COMPARE(iMode) // можно не прописывать (для возможности обратной сортировки)
  {
  }
};

void OnStart( void )
{
  int Array[] = {2, -45, 1, -5, 7, 9};

  SORT::Sort(Array, new COMPARE);
  PrintArray(Array); // -45 -5 1 2 7 9


  SORT::Sort(Array, new CompareByAbs(MODE_DESCEND));
  PrintArray(Array); // -45 9 7 -5 2 1

  return;
}

 


Alain Verleyen
Moderator
30183
Alain Verleyen 2014.11.14 20:19  
aforexpert:

It's said in MQL4 Reference that "Function templates can also be used for class methods". Then I tried th folwing code:

Compiler says: template functions overloading is not supported yet...

Does anybody successfully do template functions in a class? 

You have to duplicate the template statement :

class CTest
  {
private:

public:

                     CTest();
                    ~CTest();
   template<typename T>
   void              Func(T &data);
  };

CTest::CTest()
  {
  }
CTest::~CTest()
  {
  }
//+------------------------------------------------------------------+
template<typename T>
CTest::Func(T &data)
  {
  }
//+------------------------------------------------------------------+
Amy Liu
640
Amy Liu 2014.11.15 02:04  
angevoyageur:

You have to duplicate the template statement :

Thank you very much! I duplicate the template statement and it works! ;)
Amy Liu
640
Amy Liu 2015.12.04 09:46  
Sergey Dzyublik:
Thank you!
/
To add comments, please log in or register