Is there static cast in MQL4?

 

I was looking in the documentation and I only find run-time casting (<dynamic_cast>) but I was wondering if static_cast is available in MQL4? If not, is there a workaround to implement static polymorphism in MQL4? 

 
TraderTogami:

I was looking in the documentation and I only find run-time casting (<dynamic_cast>) but I was wondering if static_cast is available in MQL4? If not, is there a workaround to implement static polymorphism in MQL4? 

If you do it "properly",  you don't need to static cast for static polymorphisms.

Rather I suggest, without seeing your actual code, you declare your base class as template, use the derived class type as template parameter to your base class and get the type that way. Now you can cast inside the base class the (self/this) pointer to the derived type without using static cast, because you know the type by template parameter.

This works just as simple as casting types.

EDIT:
For reference:


https://en.wikipedia.org/wiki/Curiously_recurring_template_pattern#Static_polymorphism
 
Dominik Egert #:
If you do it "properly",  you don't need to static cast for static polymorphisms.

Rather I suggest, without seeing your actual code, you declare your base class as template, use the derived class type as template parameter to your base class and get the type that way. Now you can cast inside the base class the (self/this) pointer to the derived type without using static cast, because you know the type by template parameter.

This works just as simple as casting types.

EDIT:
For reference:


https://en.wikipedia.org/wiki/Curiously_recurring_template_pattern#Static_polymorphism

Can you show me an example? I was just thinking about how to implement iterators and containers without using virtual functions since those can be expensive if an overridden method get used a lot (i.e overloading the '[]' operator). 

 
TraderTogami #:

Can you show me an example? I was just thinking about how to implement iterators and containers without using virtual functions since those can be expensive if an overridden method get used a lot (i.e overloading the '[]' operator). 


The wiki link has an example of that, that's why I added that link.
 
Dominik Egert #:

The wiki link has an example of that, that's why I added that link.

On first look, I wasn't quite sure what you were trying to get me to see since I saw static_cast in the example. On a second look, are you saying to use their implementation of static_sub_func (or something similar)? 

 
TraderTogami #:

On first look, I wasn't quite sure what you were trying to get me to see since I saw static_cast in the example. On a second look, are you saying to use their implementation of static_sub_func (or something similar)? 

Here is what I mean:

template <typename DERIVED>
class base_class
{
        public:
        // Local storage
        DERIVED* ptr;

        // Constructor
        base_class(DERIVED* p_in = NULL) :
                ptr     (p_in)
        {};

        // Function
        DERIVED* my_func()
        {
                return(ptr);
        }
}

class derived_class : public base_class<derived_class>
{
        public:
        // Constructor
        derived_class()
                base_class(GetPointer(this))
        {};

        // Function
        derived_class* my_func()
        { return(GetPointer(this)); }
}
 
TraderTogami #:

On first look, I wasn't quite sure what you were trying to get me to see since I saw static_cast in the example. On a second look, are you saying to use their implementation of static_sub_func (or something similar)? 

Beyond my example from last post, you need to show code to further explain your use case.
 
Dominik Egert #:

Here is what I mean:

This makes sense, thanks 


Dominik Egert #:
Beyond my example from last post, you need to show code to further explain your use case.

template<typename T> 

interface Iterator{

   public: 

      bool has_next(); 

      T next();

      bool has_next(T& tracker); 

};


template<typename T> 

interface Container{

   public: 

      Iterator<T>* get_iterator();

};


template<typename K, typename V> 

interface Key_Container : public Container<V>{

   public: 

      int get_size();

      V operator[](const K index);

      Iterator<V>* get_iterator();

};


template<typename T> 

class Basic_Container : public Key_Container<int, T>{

   public: 

      Iterator<T>* get_iterator(){

         return new Basic_Iterator<T>(GetPointer(this)); 

      } 

};


#define foreach(Type,Var,Iterable) Type Var; for(SafePointer<Iterator<Type>> safe_it(Iterable.get_iterator()); safe_it.pointer.has_next(Var);)

Basically, I want to optimize things like that the Iterator methods, and the container's overrided operator [] so that if the collection is sufficiently large then the loop won't be taxed by a large amount of vtable lookups.

 
TraderTogami #:

This makes sense, thanks 


template<typename T> 

interface Iterator{

   public: 

      bool has_next(); 

      T next();

      bool has_next(T& tracker); 

};


template<typename T> 

interface Container{

   public: 

      Iterator<T>* get_iterator();

};


template<typename K, typename V> 

interface Key_Container : public Container<V>{

   public: 

      int get_size();

      V operator[](const K index);

      Iterator<V>* get_iterator();

};


template<typename T> 

class Basic_Container : public Key_Container<int, T>{

   public: 

      Iterator<T>* get_iterator(){

         return new Basic_Iterator<T>(GetPointer(this)); 

      } 

};


#define foreach(Type,Var,Iterable) Type Var; for(SafePointer<Iterator<Type>> safe_it(Iterable.get_iterator()); safe_it.pointer.has_next(Var);)

Basically, I want to optimize things like that the Iterator methods, and the container's overrided operator [] so that if the collection is sufficiently large then the loop won't be taxed by a large amount of vtable lookups.

This example is incomplete, does not compile, cannot test....

BTW; using interfaces in MQL is a bit pointless, as they are more or less just an abstract class.

If I understand you correctly, you want to implement the operator[] in the base class, but dont want it to be virtual. Well, then do that. You need to choose where you want your logic to be implemented. - Either use virtual functions, or concatenate function calls by casting.

template <typename DERIVED, STORAGE>
class base_class
{
    public:
    // Constructor
    base_class()
    {};

    // Function
    STORAGE operator[](const int idx) const
    { return(((DERIVED*)GetPointer(this)).operator[](idx)); }
}

template <typename STORAGE>
class derived_class : public base_class<derived_class, STORAGE>
{
    protected:
    // Local storage
    STORAGE arr[];
    
    public:
    // Constructor
    derived_class()
    {};

    // Function
    STORAGE operator[](const int idx) const
    { return(arr[idx]); }
}

Reason: