Errors, bugs, questions - page 2657

 
Stanislav Korotky:

That's the thing, the class tree has a common node CWnd (CObject is further away, at the root).

CButton -> CWndObj -> CWnd -> CObject.

If you change parameter in method to CObject, you get 2 times more errors:

A similar class hierarchy works for the non-array case. Here is the compiled code:

The question is how to make it work for an array as well?

I know a template helps, but I just want to avoid it.

IMHO, it should work without templates by right of inheritance.

I checked it as in C++.

It works. But MQL does not digest it - both with and without the index.

For C++, your example will be much clearer. Just run it and see what happens)))

class CWnd
{
public:
    int x;
    CWnd(int _x = 10) : x(_x) {}
};
class CButton : public CWnd
{
    int a;
public:
    CButton(int _a=6) : CWnd(),a(_a) {}
};

class Collection
{
public:
    Collection(CWnd* ptr,size_t size) {
        for (int i = 0; i < size; cout << ptr[i++].x<<endl);
    }
};

int main()
{
    CButton buttons[10];
    CWnd wnd[10];
    Collection data1(&wnd[0],_countof(wnd));
    cout << "------------------------------" << endl;
    Collection data2(&buttons[0],_countof(buttons));
    return 0;
}
 

Yeah, my bad. But then the following question arises. This C++ code works (already exactly right ;-)).

class Base
{
  public:
    virtual void method1(void) { cout << "2\n"; }
};

class Derived: public Base
{
  public:
    virtual void method1(void) override { cout << "3\n"; }
};

template<typename T>
class Wrapper
{
  public:
    Wrapper(T *ptr)
    {
      ptr->T::method1();
    }
};

int main()
{
  Derived d;
  d.Base::method1();   // ok
  Wrapper<Base> w(&d); // ok

  return 0;
}

Similar MQL gives error:

class Base
{
  public:
    virtual void method1(void) { Print(__FUNCSIG__); }
};

class Derived: public Base
{
  public:
    virtual void method1(void) override { Print(__FUNCSIG__); }
};

template<typename T>
class Wrapper
{
  public:
    Wrapper(T *ptr)
    {
      ptr.T::method1(); // <<< 'Base' is not a class, struct or union
    }
};


void OnStart()
{
  Derived d;
  d.Base::method1();   // ok
  Wrapper<Base> w(&d); // causes the error above
 
Stanislav Korotky:

Yeah, my bad. But then the following question arises. This C++ code works (already exactly right ;-)).

A similar MQL gives an error:

I don't know the task, but I think you're looking for something like this:

typedef void(*PTR)(void);

in MQL this is a pointer to a void func(void) function

in a class, you can declare a field of type PTR and then assign a function to it, and then "dereference the pointer" and call the function

passing functions written in procedural style into the class works without any problems, the class methods probably can't be passed that easily, you can try using dynamic_cast, but the code will get very confusing

 
Igor Makanu:

I don't know the task, but I think you are looking for something like this:

in MQL it's a pointer to a void func(void) function

in a class, you can declare a field of type PTR and then assign a function to it and then "dereference the pointer" and call the function

passing functions written in procedural style into the class works without any problems, the class methods probably can't be passed that easily, you can try using dynamic_cast, but the code will get very confusing

typedef will not work with a method.

dynamic_cast works towards inheritor (longer chain), that is, if pointer to base contains derived, then you can cast to derived and if it is not NULL (i.e. cast normal), call its method. But when situation is opposite, as in my case, there is pointer to derived then it is by definition also base. And any invocation of its virtual method finds out that derived is "sitting" in the pointer and calls overridden implementation. The base one is needed.

There is the above mentioned syntax construct in C++ for this purpose, but MQL is not C++. Apparently there's no way to do it yet.

I did a workaround but it may not work well in all the tasks.

The point of all this tambourine dancing, as always, is to keep tangled code inside the "library" and make code that uses it crystal clear and simple.

 

what to initialise rand() in the tester with ?

code:

input ulong param = 18446744073709551615;
void OnTick()
   {
   }
//+------------------------------------------------------------------+
double OnTester()
   {
      srand(GetTickCount()); 
      return(rand());
   }
//+------------------------------------------------------------------+

I don't really like this kind of pseudo-random generation:


 
Igor Makanu:

what to initialise rand() in the tester with ?

code:

I don't really like this kind of pseudo-random generation:


Help:MathRand

Note

Before calling the function for the first time, you need to useMathSrand to set the pseudorandom number generator to initial state.


Try it now with MathSrand.

Документация по MQL5: Математические функции / MathRand
Документация по MQL5: Математические функции / MathRand
  • www.mql5.com
Математические функции / MathRand - справочник по языку алгоритмического/автоматического трейдинга для MetaTrader 5
 
Vladimir Karputov:

Help:MathRand

Note

TheMathSrand function must be used before the first function call to set the pseudorandom number generator to the initial state.

Thanks Cap !

We are talking about the tester.

this code doesn't work in the tester either

input ulong param = 18446744073709551615;
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
   {
   MathSrand(GetTickCount()); 
   return(INIT_SUCCEEDED);
   }
//+------------------------------------------------------------------+
void OnTick()
   {
   }
//+------------------------------------------------------------------+
double OnTester()
   {
      return(rand());
   }
//+------------------------------------------------------------------+
 
Igor Makanu:

I think that, if a tester, there is no need to use MathSrand.

But if that doesn't help, then most likely the tester is forcing MathSrand(GetTickCount()) at some point.

Then try MathSrand(int(GetMicrosecondCount()%1000000));

Remember, GetTickCount() changes its value every 15.625 milliseconds. That's a very long time interval for a tester.

 
Nikolai Semko:

I think that, if a tester, there is no need to use MathSrand.

this contradicts the documentationhttps://www.mql5.com/ru/docs/math/mathrand

Before the first function call, you need to use MathSrand function to set pseudorandom number generator to initial state.

I don't want to go through the source code, but for neural network packages initialization by random value of NS weights is mandatory, I suspect that this was done according to MQL help material - i.e. srand() was used

i.e. the use of MQL-programs inside the tester with such NS-package will most likely take place on one processor core - the initial NS weights will have the same values, right?

it's even cooler without srand()

int OnInit()
   {
   return(INIT_SUCCEEDED);
   }
//+------------------------------------------------------------------+
void OnTick()
   {
   }
//+------------------------------------------------------------------+
double OnTester()
   {
      return(rand());
   }
//+------------------------------------------------------------------+
 
Igor Makanu:

this contradicts documentationhttps://www.mql5.com/ru/docs/math/mathrand

I don't want to look through the source code, but for neural network packages initialization by random value of NS weights is mandatory, I suspect that this was done according to MQL help material - i.e. srand() was used

i.e. the use of MQL-programs inside the tester with such NS-package will most likely take place on one processor core - the initial NS weights will have the same values, right?

even funnier without srand()

Igor, well then try MathSrand(int(GetMicrosecondCount()%16384));

I wonder how the image will change.

Reason: