错误、漏洞、问题 - 页 2661

 
Nikolai Semko:

我为将代码 简化到最低限度而道歉,这样做尤其引入了某些不准确的地方。
- 传给函数的对象具有相同的大小(代码更新)。
- 而不是哑巴输出printf("1");/printf("2");实际上是直接访问接口或对象内部,这又不允许将两个算法内联到一个调用函数中(代码更新)。

 
Sergey Dzyublik:

我为将代码 简化到最低限度而道歉,这样做尤其引入了某些不准确的地方。
- 传给函数的对象具有相同的大小(代码更新)。
- 而不是哑巴输出printf("1");/printf("2");实际上是直接访问接口或对象内部,这又不允许将两个算法内联到一个调用函数中(代码更新)。

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   
}


或者像这样。

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   
}
 
谢谢你的解决方案,
,这并不理想,因为它需要改变所用对象的结构,并涂抹了逻辑,但它是可行的。

是的,最好是在test上做一个封装函数:
   template<typename T>
   void test(A& a, T& t1, T& t2){ 
      __test(a, t1.CastToMain(), t2.CastToMain());
   }
然后在项目 中搜索所有的调用:
   c.test(b, b.CastToMain(), b.CastToMain());    // 1      should be: 1
   c.test(b, d.CastToMain(), d.CastToMain());    // 2      should be: 2  
总之,非常感谢您的帮助。
 
Sergey Dzyublik:
谢谢你的解答。
这并不理想,因为它需要改变所用对象的结构,并涂抹了逻辑,但它是可行的。

是的,在test:
上做一个封装函数比在项目中搜索所有的调用要好。

总之,非常感谢您的帮助。

是的,我同意。

 

模板函数/类缓存操作中的缺陷。
( MT5(build 2345)没有修复)**未定义行为,你创建了一个内部类型为 "C "的复杂包装对象,几次后发现它是一个完全不同的数据类型,也许是 "B",也许是 "int",随你怎么想......
( MT5(build 2345)没有修复)* 编译错误,传递函数指针作为const ref模板参数的错误。
( MT5(build 2345)没有修复)* 编译错误,B<int>对象可以在B<void*>类对象之后创建,但如果在之前做,就会发生编译错误。


模板功能/类工作中的缺陷。
( MT5(build 2345)没有修复)** 编译错误,模板函数中的错误,在显式类型转换 操作中传递的指针表现得像一个类,否则像一个指针。
( MT5(build 2345)没有修复)** 编译错误,使用内部类时模板类代码生成的错误。
( MT5(build 2345)没有修复)** 编译错误,在试图为模板函数的模板参数访问内部类时出现错误。
( MT5(build 2345)没有修复)** 编译错误,在生成模板方法/类时出现错误,模板参数 "自动完成 "过程超出了主程序代码的范围。
( MT5(build 2345)没有修复)* 编译错误,当模板类作为模板方法的返回值时,没有自动生成模板类代码的错误。
( MT5(build 2345)没有修复)* 编译错误,内部类定义的错误--定义基类时没有引用全局命名空间。
( MT5(build 2345)没有修复)*(new) 编译错误,在向模板函数传递内部结构时出现错误,产生的数据类型 不能作为模板类中另一个内部结构的基础数据类型。
( MT5(build 2345)没有修复)*(新)编译错误,当从重载的非模板函数中调用具有明确参数类型的模板函数时,存在一个错误。


与C++相比,MQL中的重载函数调用优先级不匹配框架的缺陷。
( MT5(build 2345)没有修复)*** 当有类的继承性A <= B <= C <= D,并且实现了两个重载函数,例如,一个有参数A*,一个有参数B*,那么在MQL中传递这样的函数一个对象C*或D*会导致编译错误 "对重载函数的模糊调用"。
( MT5(build 2345)没有修复)** 运行时,调用超载模板函数的优先级不匹配。
(未 被MT5(build 2345)修复)**(新)编译错误,调用重载模板函数的优先级实际上取决于模板参数的类型,理论上这不应该影响编译的结果。
( MT5(build 2345)没有修复)**(new) Compile Error,尽管有一个重载的模板函数,其签名适合所传递的参数,但在为模板函数生成代码时还是发生了编译错误。



建议。
ref- 关于允许字词和临时变量作为const ref参数传递给函数。
link- 当在项目标签中移动 项目文件 时,对于被移动的文件,如果是在ME标签中打开的,要自动更新其位置路径。
link- 在MQL中引入typedef声明功能。
链接- 关于提供强制生成默认复制构造函数和赋值运算符的可能性。

 

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

该链接是一个临时拷贝,所以你不能改变其结构

 
Andrei Trukhanovich:
引用是一个临时的副本,所以你不能改变结构

在一般情况下,你是对的...
但在特殊情况下,情况要复杂得多,事实上,给定的结构是迭代器,改变的不是它们的内容,而是它们所指向的对象。
因此,在特殊情况下问题得到了解决,我对此表示感谢。

 
Bug MT5(build 2345)的许多缺陷与当对象为模板类/结构时返回 "到位创建 "对象有关。

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();
}
 

关于交易、自动交易系统和交易策略测试的论坛

虫子,虫子,问题

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
};

如果我理解正确,那么这个函数将返回不存在的对象的指针?

 
fxsaber:

我的理解是否正确,这个函数将返回一个指向不存在的对象的指针?

是的,在这个例子中,该函数将返回一个指向不存在的对象的指针。
这段代码的主要目的是表明,一个简单的类是有工作功能的,同时对于一个模板类来说实际上是没有的。

原因: