mql5语言的特点、微妙之处以及技巧 - 页 98

 
TheXpert

有什么意义呢? 为了节省几个字节的内存? 特别是用双倍数,你会得到不同的数字(==会是假的)。

这里面没有任何意义。我喜欢这种构造,以前没有见过。

 
fxsaber:

这没有任何意义。我喜欢这个设计,以前没有见过。

啊,好的。XOR更优雅,我认为。

 
TheXpert

啊,好的。XOR更优雅,我认为。

同意的

#define  SWAP(A, B) { A ^= B; B ^= A; A ^= B; }


SZ

#define  SWAP(A, B) A ^= (B ^= (A ^= B));


来自维基。

然而,在现代CPU,XOR技术明显比使用临时变量进行交换要慢这是由于指令执行的并行化造成的。在XOR技术中,所有命令的操作数都取决于前面命令的结果,所以必须严格按照顺序执行。建议你根据具体情况在你的目标架构上测试这两种选择的速度。

 
恶梦。
 
fxsaber:

来自维基

如果前面的加/减法是并联的,怎么办?)

 
塔拉斯-斯洛博亚尼克

如果他们与以前的加/减法相平行呢?)

依赖于序列的算法不会并行化。

有时间变量的算法则不然,所以它是可并行的。

 
没有...
 

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

虫子,虫子,问题

伊利亚斯, 2016.08.24 11:08

数组("里面")存储分配的--在数组 的多少个元素 下分配。

与分配的工作逻辑(条件代码)。
ArrayResize(arr,int size,int reserve)
  {
   if(arr.allocated<size)
      if(!ArrayAllocateMemory(arr,size+reserve))  // -> arr.allocated=size+reserve;
         return(-1);
   //---
   CallConstructorsOrDestructors(arr,size);
   //---
   arr.size=size;
   return(size);
  }
 

继续我们的 "磨磨蹭蹭 "专栏,今天的主题是模板热,或者如何摆脱模板的屁股 )

经常需要通过引用传递一些变量作为模板参数来修改它,但不幸的是,模板规范不允许你像普通函数那样明确指定参数的 恒定性。

void Modify(int&) { }  // Принимает только не константы

template<typename T>
void Modify(T& a) {  } // Принимает любые аргументы

这可能会造成不便,当参数沿着模板链下行到目的地时,它变成了一个常量,不能被改变。 而这个错误发生在库的某个深处。 检测原始模板是从哪里调用的,有时是一个非常困难的任务。

template<typename T>
void f0(T& a)  { a=10; }  // 'a' - constant cannot be modified

template<typename T>
void f1(T& a)  { f0(a); }

template<typename T>
void f2(T& a)  { f1(a); }

void Source() { const int a=0;  f2(a); }

这在普通的IDE中不是一个问题。例如,VS有一个完整的模板路线跟踪,所以只需在正确的地方点击,它就会带你到那里。 但在MQL中这是一个问题。这可能会成为模板制作者的一个持续的头痛问题。

但它可以被修复。为了做到这一点,你可以使用模板重载。

template<typename T>
void Modify(const T&); // Фэйковый запрещённый шаблон

template<typename T>
void Modify(T& a) { a=10; }

现在,当试图传递常数时,上层模板将被调用。但这并不是一个充分的解决方案,因为首先,这个错误只在编译可执行文件时发生(而在.mqh中不是),其次,这个错误发生在模板声明的地方,而不是我们想找到的调用的地方。 所以我们继续前进。

当模板是一个类的方法时,一切都很简单:我们把假模板放到一个私有部分,当我们试图调用它时,会得到一个访问错误。

在C++中,这个问题不能仅靠重载来解决,我们需要额外的功能,这在MQL中是不存在的。 但在这里,MQL的强大武器--错误--向我们伸出了援手) 在这种情况下,这样的一个bug对我们非常有用 )
我们给我们的假模板添加了一个额外的参数T2,现在,当试图调用错误的模板时,我们在调用点得到一个错误。

template<typename T, typename T2>
void Modify(const T&);  // Запрещаем

template<typename T>
void Modify(T& a) { a=10; }

void Source()
{ 
  int a, const b=0;
  Modify(a);  // всё ОК
  Modify(b);  // template mismatch
}

问题解决了。在C++中,底层模板当然会在两种情况下被调用,因为那里没有这样的错误。

这种方法在另外一种情况下也很有用:当我们需要明确控制函数参数的类型,禁用隐式转换时。
例如,该函数应该只接受datetime参数,抑制各种int和其他东西。
我们做了一个相应的变体。

template<typename T, typename T2>
void MyFunc(T);  // Запрещаем

void MyFunc(datetime time) {  }

现在,和之前的情况一样,当试图传递一个未解决的类型时,将抛出一个编译错误。

顺便说一下,我总是对datetime做出这样的禁止,我认为开发者完全允许对它进行隐式转换,而且没有对编译器 发出任何警告(除了long和string),这是毫无意义的。甚至任何枚举都可以自由地投给它而没有任何警告。

还有一个相反的问题:只禁止某一种类型的调用。解决办法将是一样的。

template<typename T,typename T2>
void MyFunc(datetime);  // Запрещаем

template<typename T>
void MyFunc(T arg) {  }


如上所述,类内的一切问题都是在没有多余参数的情况下解决的。

 
Alexey Navoykov:

继续我们的 "令人眼花缭乱的手 "专栏,今天的主题是模板热,或如何摆脱模板的屁股 )

经常需要通过引用传递一些变量作为模板参数来修改它

出现了不加修改地通过参照物的需要--对于速度,或一个对象。

然而,不幸的是,现有的C++模板规范不允许明确地指定参数的非恒定性,就像在通常的函数中那样。

这可能会造成不便,当参数顺着模式链走到目的地时,发现它是一个常数,无法改变。 而这个错误发生在库的某个深处。 检测原始模板是从哪里调用的,有时是一个非常困难的任务。

在MQL5中,是否有发生这种问题的真实例子?

在正常的IDE中,这不是一个问题。例如,VS显示模板路线的全部轨迹,所以只要在正确的地方点击,就会直接到达目的地。 但在MQL中,这确实是个问题。这可能会成为模板制作者的一个持续的头痛问题。

但它可以被修复。为了做到这一点,你可以使用模板重载。

现在,当试图传递常数时,上层模板将被调用。但这并不是一个充分的解决方案,因为首先,这个错误只在编译可执行文件时发生(而在.mqh中不是),其次,这个错误发生在模板声明的地方,而不是我们想找到的调用的地方。 所以我们继续前进。

当模板是一个类的方法时,一切都很简单:我们把假模板放到一个私有部分,当我们试图调用它时,会得到一个访问错误。

从语法上看,这个问题在C++中根本无法解决,据我所知。但我们很幸运,MQL不是C++--它有一些bug)而在这种情况下,这些bug可以被处理成最好的优势。)

我们给我们的假模板添加了一个额外的参数T2,当试图调用错误的模板时,在调用点得到了一个错误。

问题解决了。当然,在C++中,底层模板在两种情况下都会被调用。

真正方便的例子是缺失的。

这个方法在另外一种情况下可能会派上用场:如果你需要明确控制函数参数的类型,通过禁用隐式转换。
例如,该函数必须只接受datetime参数,锁定各种int和其他东西。
我们做了一个相应的变体。

现在,和之前的情况一样,当试图传递一个未解决的类型时,将抛出一个编译错误。

在MQL5中,一旦出现这种可能性,它似乎就会被充分地使用。如果我理解正确,这是一个标准。

顺便说一下,我总是对datetime做出这样的禁止。 我认为开发者根本就不应该允许对它进行隐式转换,甚至没有对编译器发出 任何警告(除了long和string)。甚至任何枚举都可以自由地投给它而没有任何警告。

还有一个相反的问题:只禁止某一种类型的调用。解决办法将是类似的。

体验到数据时间的便利性,因为它现在的行为。什么时候有问题?


总而言之,这是一个非常好的、有用的帖子,谢谢!