mql5言語の特徴、微妙なニュアンスとテクニック - ページ 98

 
TheXpert です。

特にdoubleの場合、異なる数値が得られる(==が偽になる)ため、意味がありません。

意味がないんです。この構成はいいですね、今まで見たことがありません。

 
fxsaber

意味がないんです。今まで見たことのないデザインで気に入っています。

xorの方がよりエレガントです。

 
TheXpert です。

xorの方がよりエレガントです。

同意

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


エスゼット

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


Wikiより。

しかし、最近のCPUではXORのテクニックは、交換用の一時的な変数を使うよりも大幅に遅く なる。これは、命令実行の並列化によるものです。XOR技術では、すべてのコマンドのオペランドは前のコマンドの結果に依存するため、厳密に順を追って実行する必要があります。ターゲット・アーキテクチャ上で、両方の選択肢の速度をケースバイケースでテストすることが推奨されます。

 
ナイトメア
 
fxsaber

Wikiより

前の加算/減算が並列化されている場合はどうなりますか?)

 
タラス・スロボジャニク

前の足し算・引き算を平行移動させたらどうなる?)

シーケンス依存のアルゴリズムは並列化しない。

一時的な変数を持つアルゴリズムはそうではないので、並列化可能である。

 
いや...
 

トレーディング、自動売買システム、トレーディング戦略のテストに関するフォーラム

バグ、バグ、質問

イリヤス さん 2016.08.24 11:08

配列("inside")には、割り当てられた-いくつの要素の 下に配列が割り当てられて いるかが格納されます。

アロケートされたものを扱うロジック(条件分岐コード)です。
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の強力な武器であるバグが私たちを助けてくれるのです。
偽のテンプレートに追加のパラメータ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を除く)。どんなenumでも、警告を出さずに自由にキャストできる。

また、逆の問題として、ある型の呼び出しだけを禁止することもある。解決策も同じでしょう。

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++でないことは幸いで、バグがあります ) そして、この場合、これらのバグは回避することができます)。

偽テンプレートに追加のパラメータT2を追加し、間違ったテンプレートを呼び出そうとすると、呼び出しポイントでエラーが発生します。

問題解決C++では、もちろんどちらの場合でも一番下のテンプレートが呼び出されます。

利便性の実例が欠落している。

この方法は、もうひとつ便利な場合があります。それは、暗黙の変換を無効にして、関数の引数の型を明示的に制御する必要がある場合です。
例えば、この関数はdatetimeの引数のみを受け取り、intやその他のあらゆる種類のものをロックアウトしなければなりません。
対応するバリアントを作っています。

さて、前のケースと同様に、未解決の型を渡そうとすると、コンパイルエラーが発生します。

MQL5では、可能性が出てきた段階で、存分に使っているようです。私の理解が正しければ、それは標準的なものです。

ところで、私はいつもdatetimeを禁止しているのですが、開発者は暗黙のうちに変換させるべきでなく、しかもコンパイラに 何の警告も出さない(longとstringを除く)のがいけないと思います。どんなenumでも、警告を出さずに自由にキャストできる。

また、逆の問題として、ある型の呼び出しだけを禁止することもある。解決策も似たようなものでしょう。

datetimeが今と同じように振る舞うことの便利さを体験する。問題はいつ?


全体として、とても良い、役に立つ記事です。