Errors, bugs, questions - page 2661

 
Nikolai Semko:

I apologise for simplifying the code to a minimum, introducing certain inaccuracies by doing so, in particular:
- objects passed to the function have the same size (code updated);
- instead of dumb output printf("1");/printf("2"); the interface or object internals are actually accessed directly, this in turn does not allow to inline two algorithms into a single call function (code updated).

 
Sergey Dzyublik:

I apologise for simplifying the code to a minimum, introducing certain inaccuracies by doing so, in particular:
- objects passed to the function have the same size (code updated);
- instead of dumb output printf("1");/printf("2"); the interface or object internals are actually accessed directly, this in turn does not allow to inline two algorithms into a single call function (code updated).

class C{
public:
   struct A{
   public:
      char aaa;
      
      A (char value = 0) : aaa(value){}
      void set(char value){
         aaa = value; 
      };
      uint Type(){return 0x778F6712;}
      char get(){return aaa;}
      A Get() {return this;}
   };
   
   void test(A&, A& a1, A& a2){
      printf("1");
      a1.aaa = a2.aaa;
   }
   
   template<typename T>
   void test(A& a, T& d1, T& d2){
      if (a.Type()== d1.Type()) test(a,d1.Get(),d2.Get());
      else {
      printf("2");
      d1.set(d2.get());}
   }
};

struct B : public C::A{};


struct D{
private:
   char data;
public:  
   D(char value = 0) : data(value){}
   void set(char value){
      data = value; 
   };
   uint Type(){return 0x308FD7FE;}
   char get(){return data;}
   D Get() {return this;}
};


void OnStart(){
   C c;

   B b;
   D d;
   
   c.test(b, b, b);    // 1      should be: 1
   c.test(b, d, d);    // 2      should be: 2   
}


Or like this:

class C{
public:
   struct A{
   public:
      char aaa;
      
      A (char value = 0) : aaa(value){}
      void set(char value){
         aaa = value; 
      };
      char get(){return aaa;}
      A Get() {return this;}
   };
   
   void test(A&, A& a1, A& a2){
      printf("1");
      a1.aaa = a2.aaa;
   }
   
   template<typename T>
   void test(A& a, T& d1, T& d2){
      printf("2");
      d1.set(d2.get());
   }
};

struct B : public C::A{};


struct D{
private:
   char data;
public:  
   D(char value = 0) : data(value){}
   void set(char value){
      data = value; 
   };
   char get(){return data;}
   D Get() {return this;}
};


void OnStart(){
   C c;

   B b;
   D d;
   
   c.test(b.Get(), b.Get(), b.Get());    // 1      should be: 1
   c.test(b.Get(), d.Get(), d.Get());    // 2      should be: 2   
}
 
Thanks for the solution,
it's not ideal as it requires changes in the structure of used objects and smears the logic, but it works.

And yes, it's better to make a wrapper function over test:
   template<typename T>
   void test(A& a, T& t1, T& t2){ 
      __test(a, t1.CastToMain(), t2.CastToMain());
   }
Than search through the project for all the calls:
   c.test(b, b.CastToMain(), b.CastToMain());    // 1      should be: 1
   c.test(b, d.CastToMain(), d.CastToMain());    // 2      should be: 2  
Anyway, thanks a lot for your help.
 
Sergey Dzyublik:
Thanks for the solution,
It's not ideal because it requires changes in the structure of used objects and smears the logic, but it works.

And yes, better to make a wrapper function over test:
than to search through the project for all the calls:

Anyway, thanks a lot for your help.

Yes, I agree.

 

Defects in template function/class cache operation:
(not fixed by MT5(build 2345)) ** Undefined Behavior, you create a complex wrapped object with internal type "C" several times and it turns out to be a completely different data type, maybe "B", maybe "int", whatever you want...
(not fixed by MT5(build 2345)) * Compile Error, bug on passing a function pointer as a const ref template argument.
(not fixed by MT5(build 2345)) * Compile Error, B<int> object can be created after B<void*> class object, but compile error occurs if done before.


Defects in template function/class work:
(not fixed by MT5(build 2345)) ** Compile Error, bug inside template function, passed pointer withinexplicit type conversion operation behaves like a class otherwise like a pointer.
(not fixed by MT5(build 2345)) ** Compile Error, bug with template class code generation while using internal class.
(not fixed by MT5(build 2345)) ** Compile Error, bug on attempt to access internal class for template parameter of template function.
(not fixed by MT5(build 2345)) ** Compile Error, bug on generating template method/class, the template parameter "autocompletion" process goes out of scop into main program code.
(not fixed by MT5(build 2345)) * Compile Error, bug with absence of autogenerating template class code when the template class acts as return value for the template method.
(not fixed by MT5(build 2345)) * Compile Error, bug in internal class definition - no reference to global namespace when defining a base class.
(not fixed by MT5(build 2345)) *(new) Compile Error, bug in passing internal struct to template function, resultingdata type can not be used as a base data type for another internal struct in template class.
(not fixed by MT5(build 2345)) *(new) Compile Error, a bug when calling a template function with explicit argument types when called from an overloaded non-template function.


Defects in the framework of overloaded function call priority mismatch in MQL compared to C++:
(not fixed by MT5(build 2345)) *** Compile Error when there is class inheritance A <= B <= C <= D and two overloading functions are implemented, for example, one with parameter A* and one with parameter B*, then passing in such function an object C* or D* in MQL causes a compilation error "ambiguous call to overloaded function".
(not fixed by MT5(build 2345)) ** Runtime, Priority mismatch for calls of overloaded template functions.
(not fixed by MT5(build 2345)) **(new) Compile Error, the priority of calls of overloaded template functions actually depends on the type of template parameter, which theoretically should not affect the result of compilation.
(not fixed by MT5(build 2345)) **(new) Compile Error, a compilation error occurs when generating code for a template function despite the fact that there is an overloaded template function with a suitable signature for the passed parameters.



Suggestions:
ref- on allowing literals and temporary variables to be passed as const ref arguments to a function.
link- whenmoving projectfiles in the Project tab, for moved files that are open and in ME tabs, to automatically update their location path.
link- to introduce typedef declaration functionality in MQL.
link- about providing possibility to force generation of default copy constructors and assignment operators.

 

Sergey Dzyublik:
Спасибо за вариант решения

the link is a temporary copy, so you can't change the structure

 
Andrei Trukhanovich:
The reference is a temporary copy, so you can't change the structure

You are right in general case...
But in particular cases it is much more complicated and in fact the given structures are iterators and it is not their contents that are changed, but the objects to which they refer.
So the problem is solved in the special case and I am grateful to you for that.

 
Bug MT5 (build 2345) many defects related to return "in place created" object when the object is a template class/structure:

class A{
public:
   A(int, int, int){};  
   A(const A&){}
   A(const A*){}
};

// simple class type
A* test_a_ptr_ptr(){
   return &A(1,2,3);               //OK
};

A test_a_class_class(){
   return A(1,2,3);                //OK
};

A test_a_ptr_class(){
   return &A(1,2,3);               //OK
};


template<typename T>
class B{
public:
   B(int &){}
   B(long){}
   B(int, int, int){};  
   B(const B&){}
   B(const A*){}
};

// template class type
B<A*> test_b_class_class(){
   B<A*> b(1);
   int x = 22;
   
   return B<A*>();              // Compile Error: ambiguous call to overloaded function with the same parameters: "B(long)" and "B(const A*)"
   return B<A*>(1,2,3);         // Compile Error: only one argument is acceptable, argument should be castable to int
   return B<A*>(x);             // Compile Error: argument is passed by value instead of by reference.
   return B<A*>((A*)NULL);      // Compile Error: 'int' - invalid cast operation        
   return B<B<B<long>>>(1);     // Compile Error: OK, template parameter type does not provide any effort on compilation result
   
   return b;
};

B<A*>* test_b_ptr_ptr(){
   B<A*> b(1);
   
   return &B<A*>(1);            // Compile Error: '&' - illegal operation use
   return &b;                 
};


void OnStart (){ 
   // simple class type
   A* a_ptr = test_a_ptr_ptr();
   A a0 = test_a_class_class();
   A a1 = test_a_ptr_class();
   
   // template class type
   B<A*> b0 = test_b_class_class();
   B<A*>* b_ptr = test_b_ptr_ptr();
}
 

Forum on trading, automated trading systems and trading strategy testing

Bugs, bugs, questions

Sergey Dzyublik, 2020.03.01 12:53

class A{
public:
   A(int, int, int){};  
   A(const A&){}
   A(const A*){}
};

// simple class type
A* test_a_ptr_ptr(){
   return &A(1,2,3);               //OK
};

If I understand correctly, then this function will return the pointer to the object which does not exist?

 
fxsaber:

Do I understand correctly that this function will return a pointer to a non-existent object?

Yes, in this example the function will return a pointer to a non-existent object.
The main purpose of this code is to show that there is working functionality for a simple class and at the same time there actually is none for a template class.