汎用クラスライブラリ - バグ、説明、質問、使用上の特徴、提案 - ページ 20

 
セルゲイ・デジュブリク

1.あいまいな行動をなくす。
CPrimeGenerator::ExpandPrime にパラメータとして "INT_MAX - 10" を渡すと、結果 "INT_MAX" が返されます。
CPrimeGenerator::GetPrime にパラメータとして "INT_MAX - 10" を渡すと、同じ結果が返されます: "INT_MAX - 10".

どちらの場合も、返される値は素数ではないので、ユーザーに誤解を与えることになります。

1点目について。

ここに曖昧さはありません。

GetPrimeメソッドは上から最も近い素数を返すべきですが、INT_MAX- 10からINT_MAXまでの区間には1つもないので、INT_MAX - 10が返されます。

ExpandPrimeメソッドは、まず入力値を2倍にし、受け取った数値からGetPrimeメソッドを呼び出す。

さらに、ExpandPrimeはINT_MAXオーバーランのチェックを備えています。

   if((uint)new_size>INT_MAX && INT_MAX>old_size)
      return INT_MAX;
   else
      return GetPrime(new_size);

これらのメソッドの動作の背後にあるロジックは、全く曖昧さのない正しいものだと私は考えています。


第2、第3の項目に関して。

あなたが提案する変更は、CHashMapのサイズが非常に大きい場合、ほとんどの場合、エッジの問題にしか関係しません。ただし、それらがパフォーマンスに良い影響を与えるという保証はありませんので、ご提案いただいた変更の正しさについては、別途調査が必要です。

 
ロマン・コノペルコ

ここに曖昧さはありません。
GetPrimeメソッドは上から最も近い素数を返すべきですが、INT_MAX- 10とINT_MAXの間には何もないので、INT_MAX - 10が返されます。
ExpandPrimeメソッドは、まず入力値を2倍にし、受け取った数値からGetPrimeメソッドを呼び出す。
さらに、ExpandPrimeはINT_MAXオーバーランのチェックを備えています。
これらのメソッド動作のロジックは、全く曖昧さのない正しいものです。


1.この関数は、素数ではなく未知数を返すことがあります。
このデータをどう使うかはユーザーの問題で、ロングにキャストしてスーパーコンピューター機能に渡すかもしれないし、誰も気にしない。
実は、デフォルトで宣言され、関数に期待されるものとは異なるものを返すことがあるのです。

2.関数呼び出しが素数を返したかどうか、他の何かでないかを確認するにはどうしたらよいでしょうか。
単純にINT_MAXと比較することはできません。
INT_MAXより小さい最後の利用可能な素数と比較する必要があります。
そのたびに、これらの関数の呼び出し結果を、ある魔法の数字と比較して、すべてがうまくいっていることを確認するのですが、私は不条理だと感じています。

 
セルゲイ・デジュブリク

1.関数は素数ではなく、無名数を返すことがあります。
このデータをどう使うかはユーザーの問題であり、longにキャストしてスーパーコンピューティングの関数に渡すかもしれない。
実は、デフォルトで宣言され、関数に期待されるものとは異なるものを返すことがあるのです。

2.関数呼び出しが素数を返したかどうか、他の何かでないかを確認するにはどうしたらよいでしょうか。
単純にINT_MAXと比較することはできません。
INT_MAXより小さい最後の利用可能な素数と比較する必要があります。
これらの関数の呼び出しの結果を、毎回何らかのマジックナンバーと比較して、すべてが正しいことを確認するというのは、私には無茶な話としか思えません。

1.GetPrimeメソッドで非単純数を得るというあなたのケースは、私がこれまでに遭遇した唯一のものです。この事件は、素数生成時のチェックを変更することで解決する予定です。

//--- outside of our predefined table
   for(int i=(min|1); i<=INT_MAX; i+=2)
     {
      if(IsPrime(i) && ((i-1)%s_hash_prime!=0))
         return(i);
     }
   return(min);

2.CPrimeGenerator::IsPrime メソッドを用いて、簡便に数を確認 する。

 

Generic/ArrayList.mqhにある私のArrayListからあなたのArrayListに切り替えようとしました。

MEは". "の後に何も与えません。

値を取得するにはどうすればよいですか?Get()と[]がクラス内にありません。

また、ポインタの配列があるかもしれないことも考慮されていません。

そして、このライブラリーは誰が作っているのでしょうか?

以下は、私が作成したJavaのArrayListのバージョンです。

ファイル:
ArrayList.mqh  46 kb
 
このバリアントを作成したときには、クラステンプレートはありませんでした。
 
ロマン・コノペルコ

Genericコレクションがクラスオブジェクトと正しく動作するためには、これらのクラスはEqualsとHashCodeメソッドが定義されているIEqualityComparableインターフェースを実装している必要があります。つまり、ハッシュコードの計算方法をユーザーが設定しなければならないのだが、.Netで行われていたような、例えばMQL5による自動実装は不可能なので、今のところこれしか選択肢がないのだ。

では、なぜあなたのテンプレートはどんな型でも動作するのか、プログラマの誤解を招きます。 IEqualityComparableを継承したクラスだけが正しく動作するなら、コンパイラレベルで他の型を扱うのを禁止すべきです。

このコードを思い出してみてください。

//+------------------------------------------------------------------+
//| Returns a hashcode for custom object.                            |
//+------------------------------------------------------------------+
template<typename T>
int GetHashCode(T value)
  {
//--- try to convert to equality comparable object  
   IEqualityComparable<T>*equtable=dynamic_cast<IEqualityComparable<T>*>(value);
   if(equtable)
     {
      //--- calculate hash by specied method   
      return equtable.HashCode();
     }
   else
     {
      //--- calculate hash from name of object
      return GetHashCode(typename(value));
     }
  }

この機能に置き換えるべきだと思います。

template<typename  T>
int GetHashCode(IEqualityComparable<T> &value)
  {
    return value.HashCode()
  }
 
アレクセイ・ナヴォイコフ

では、なぜあなたのテンプレートはどんな型でも動作するのか、プログラマの誤解を招きます。 もしIEqualityComparableを継承したクラスだけが正しく動作するなら、コンパイラレベルで他の型を扱うのを禁止すべきです。

このタイプでは動作に不便を感じるでしょう。標準型のGetHashCodeオーバーロードは、ハッシュコード取得のインターフェースを示しています。


何が困るって、それがないことです。

template<typename T>
interface IEqualityComparable
  {
//--- method for determining equality
   bool              Equals(T & value);
//--- method to calculate hash code   
   int               HashCode(void);
  };


I.e.forオブジェクトのバマー今。

 
fxsaber

これでは仕事にならない。標準型に対する GetHashCode オーバーロードは、ハッシュコードを取得するためのインターフェイスを示す。

そして、何が便利かというと、インターフェースをサポートしていないクラスのenumやポインタをこの関数に渡すと、クラス名が返ってくるだけなのです(笑)。 そして何より、このコードはあたかも全てが正常であるかのように動作し、コンパイルもできます。

 
アレクセイ・ナヴォイコフ

インターフェースに対応していないクラスのenumやポインタをこの関数に渡すと、クラス名が返ってくるだけとは。 すごいハッシュだ)そして最も重要なことは、コードが動作し、すべてが正常であるかのようにコンパイルできることだ。 これはそうではない。

そう、彼らはゴミを作ったのだ。言語レベルでのインターフェースのサポートがなければ、十分に機能しないことは明らかなのに、軽率にもNetFrameworkからコピー&ペーストしてしまったのです。6~7年前のMQコードのレベルを覚えているが、今はその頃と比べるとゴミのようなものだ。

 
Alexey Navoykov:

この関数にインターフェースに対応していないクラスのenumやポインタを渡すと、クラス名が返ってくるだけというのは便利ですね。 いいハナシです)そして何より、このコードはあたかもすべてがうまくいったかのように動作し、コンパイルされます。 これはそうではありません。

そうですね、なぜ動かないのかという長い問題に対処するよりも、すぐにコンパイルエラーが 出る方がいいですよね。

正直なところ、なぜそこにインターフェイスを貼り付けたのかもわかりません。結局のところ、必要な型に対してGetHashCodeをオーバーロードすればよく、IEqualityComparableを作り始める必要はありません。