I finally found a good use for function pointers.

 

Here is an example of putting function pointers to good use. Those who know javascript or python will likely recognize this pattern immediately. 


This is a generic object vector that I frequently use, and I've added a filter method which takes a function as an argument and returns a pointer to a new vector. The new vector is added to a "garbage collector" so there is no need for memory management, however, if the scope of the original (non-filtered) collection runs out before the scope of the filtered vector then there will be an error due to the object getting deleted. 


objvector

#include <arrays/arrayobj.mqh>

typedef bool (*FilterFunc) (CObject*);

template <typename T>
class objvector : public CArrayObj {
protected:
   CArrayObj   m_garbage_collector;
public:
   T operator[](const int index)const{return this.At(index);}
   objvector<T>* filter(FilterFunc func) {
      objvector<T>* new_vector = new objvector<T>();
      m_garbage_collector.Add(new_vector);
      new_vector.FreeMode(false);
      int size = this.Total();
      for (int i=0; i<size; i++) 
         if (func(this[i])) 
            new_vector.Add(this[i]);
      return new_vector;
   }
};


Use example. 

class Trade : public CObject {
public:
   int  ticket;
   double profit;
   Trade(int _ticket) {
      if (OrderSelect(_ticket, SELECT_BY_TICKET)) {
         ticket = _ticket;
         profit = OrderProfit();
      }
   }
};


bool fWin(CObject *obj) {
   return ((Trade*)obj).profit > 0;
}

bool fLose(CObject *obj) {
   return ((Trade*)obj).profit < 0;
}

bool fSymbol(CObject *obj) {
   return (OrderSelect(((Trade*)obj).ticket, SELECT_BY_TICKET)
      && OrderSymbol() == _Symbol);
}


void OnStart() {
   objvector<Trade*> all, *winners, *losers, *my_symbol_losers;
   for (int i=0; OrderSelect(i, SELECT_BY_POS, MODE_HISTORY); i++)
      all.Add(new Trade(OrderTicket()));
   
   winners = all.filter(fWin);
   losers = all.filter(fLose);
   my_symbol_losers = losers.filter(fSymbol);
   
   printf("winners=%d, losers=%d, all=%d", winners.Total(), losers.Total(), all.Total());
}
 
nicholish en:

Here is an example of putting function pointers to good use. Those who know javascript or python will likely recognize this pattern immediately. 


This is a generic object vector that I frequently use, and I've added a filter method which takes a function as an argument and returns a pointer to a new vector. The new vector is added to a "garbage collector" so there is no need for memory management, however, if the scope of the original (non-filtered) collection runs out before the scope of the filtered vector then there will be an error due to the object getting deleted. 


objvector


Use example. 


This is rather old, but still I'd like to thank for the good template and reference! :) 

 

nicholish en: Here is an example of putting function pointers to good use. Those who know javascript or python will likely recognize this pattern immediately.   

in C++ it (function pointer) is a functor or callback... it is easy way  to use a function as a parameter for another function... passing pointer to it (the first) as an argument...

general good explanation was on youtube about  typedef  Function Pointers in MQL4_ and also here example was and here ...

& thank you for the generalized version to deal with pointers in function (with last being used as function pointer)... though it is still a little bit complicated for me

Documentation on MQL5: Constants, Enumerations and Structures / Named Constants / Predefined Macro Substitutions
Documentation on MQL5: Constants, Enumerations and Structures / Named Constants / Predefined Macro Substitutions
  • www.mql5.com
Predefined Macro Substitutions - Named Constants - Constants, Enumerations and Structures - MQL5 Reference - Reference on algorithmic/automated trading language for MetaTrader 5
 
nicholish en:

new_vector.FreeMode(false); 

but why did you switch-off the CArrayObject's responsibility for freeing the memory ??

 
Put the cart before the horse:本末倒置(in Chinese)
 

I suppose the reason is Lifetime in the scope & the goal is to return new_vector (or dest_arr) out of scope... taking into consideration

In MQL4 functions can't return objects, but they can return the object pointer.

References: Modifier & and Keyword this - Data Types - Language Basics - MQL4 Reference
References: Modifier & and Keyword this - Data Types - Language Basics - MQL4 Reference
  • docs.mql4.com
References: Modifier & and Keyword this - Data Types - Language Basics - MQL4 Reference
 

I finally found out why to use FreeMode(false); else -

The element will not change if an invalid pointer (for example, NULL) is passed as a parameter. If the memory management is enabled, the memory of a replaced element is deallocated.

- to avoid this deallocation when needed (e.g. in Update))
Documentation on MQL5: Standard Library / Data Collections / CArrayObj / Update
Documentation on MQL5: Standard Library / Data Collections / CArrayObj / Update
  • www.mql5.com
Update(int,CObject*) - CArrayObj - Data Collections - Standard Library - MQL5 Reference - Reference on algorithmic/automated trading language for MetaTrader 5