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

 
Alexey Volchanskiy:

MSDNではリングバッファと呼んでいますが、この名前は私が考えたわけではありません。

にリンクします。

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

...そして、値だけでなく、参照による引数への変換で終了します。

リテラルに問題がある可能性があります

 
TheXpert:

をスタジオにリンクします。

リテラルに問題がある可能性があります

その記事を再度検索するのは怠慢だが、少しは引き伸ばした。リングシングルまたはダブルリンクリストはリンクリストをベースにしていますが、最後の要素に一番最初の要素へのリンクが格納されています。

 
TheXpert:

リテラルに問題がある可能性があります

いいえ、「値」クラスは、純粋にラッパーとして、ベースの「参照」クラスから継承しています。そのため、必要なバージョンのクラスを選択し
 
Alexey Volchanskiy:

シングルまたはダブルリンクリストは、リンクリストをベースにしていますが、リンクリストの最後のアイテムは、一番最初のアイテムへのリンクを格納します。

そこがポイントです。"ベース "であって、"置き換え "ではありません。 ここでも開発者が追加コンテナにすることを誰も止めていないのです。一般的な概念で代用するのではなく
 
Alexey Navoykov:

おそらく、これらのクラスを移植した人は、コードを単純化することで、自分の生活を簡素化しようと考えたのでしょう。 2つのポインタm_firstとm_lastの代わりに、1つのポインタm_headにしたのです...。

LinkedListクラス自体は正しく移植されており、ポインタの頭は1つだけで、それが最初と最後の両方になっています。つまり、内部実装は確かにループしているが、外部動作はループしていない。 MQはCLinkedNodeクラス(NextとPreviousメソッド)でエラーになっている。 その本来の実装はこんな感じだ。

        public LinkedListNode<T>? Next
        {
            get { return next == null || next == list!.head ? null : next; }
        }

        public LinkedListNode<T>? Previous
        {
            get { return prev == null || this == list!.head ? null : prev; }
        }

そして、それをMQLに移植したのが、こちらです。

   CLinkedListNode<T>* Next(void)                      { return(m_next); }
   CLinkedListNode<T>* Previous(void)                  { return(m_prev); }

不注意で間違えたのかもしれません。

しかし、一般的には、私もdotnetの実装には少し驚いています。 なぜ、1つのヘッドではなく、リスト自体に2つのポインタ(最初と最後)を作ることができなかったのでしょうか。もちろん、ノードの挿入/削除の処理は遅くなりますが、それよりも優先順位の高い反復処理を高速化できます。 NextとPreviousは、追加されたノードよりも頻繁に呼び出されることは間違いありません。 そうだったんですね、メルコムソフトも同じかと思いました。 でも気にしないでください )

ところで、MQには、CLinkedListNodeとCRedBlackTreeNodeの実装に、もう一つバグがあります。(m_value を除く) は、リストクラス自身によってのみ変更されることを意図しています。 他の誰も変更する必要がありません。 そのため、dotnet では内部フィールドとなっています。MQはこれらのフィールドを変更するメソッドを公開し、少なくとも具体的な名前を付けていたはずなのですが...。が、いや、いつもの名前だけ。

void              Next(CLinkedListNode<T>*value)     { m_next=value; }
 

みなさん、こんにちは。

CHashMapの項目を削除するには、CopyToでコピーして手動で削除する以外に方法はないのでしょうか?

 

このライブラリの実装の悪さには、他にもいくつか原因があります。 CKeyValuePairというクラスは、なぜかIComparableインターフェイス(したがってIEqualityComparableも)を継承していて、ユーザ型のKeyもこれらのインターフェイスをサポートしなければなりません。 独自のComparerを定義すればその必要はありませんが。 本家ではKeyValuePairには当然ながらインターフェイスはありません。

どんどん突っ込めば、もっと変なものが出てきますよ。

template<typename TKey,typename TVal>
CHashMap::CHashMap(IEqualityComparer<TKey>*comparer): m_count(0),
                                                      m_free_list(0),
                                                      m_free_count(0),
                                                      m_capacity(0)
  {
//--- check equality comaprer
   if(CheckPointer(comparer)==POINTER_INVALID)
     {
      //--- use default equality comaprer    
      m_comparer=new CDefaultEqualityComparer<TKey>();
      m_delete_comparer=true;
     }
   else
     {
      //--- use specified equality comaprer
      m_comparer=comparer;
      m_delete_comparer=false;
     }
  }

つまり、壊れたポインタを誤ってコンストラクタに渡してしまうと、プログラムは平穏に動作し続けるだけでなく、そのロジックも変わってしまうのだ!

コンストラクタは次のようなものです。

template<typename TKey,typename TVal>
CHashMap::CHashMap(IEqualityComparer<TKey>*comparer): m_count(0),
                                                      m_free_list(0),
                                                      m_free_count(0),
                                                      m_capacity(0),
                                                      m_comparer(comparer),
                                                      m_delete_comparer(false)
{ }

また、POINTER_INVALIDも ありません。また、デフォルトの比較対象には、別のコンストラクタのシグネチャがあります。

 
CQueue<T>テンプレートに 任意のクラスをTパラメータとして正しく適用する例はありますか?
 
すでに並行スレで禁止を求める。
 

コードがコンパイルできない理由を教えてください。

#include <Generic\HashMap.mqh>
void OnStart()
  {
   CHashMap<ENUM_CHART_PROPERTY_INTEGER,int> mapI;    // эта срока компилируется без ошибок
   CHashMap<ENUM_CHART_PROPERTY_DOUBLE,double> mapD;  // здесь ошибки компиляции: 'NULL' - cannot convert enum  HashMap.mqh     21      39. 'NULL' - cannot convert enum        HashMap.mqh     462     30
   CHashMap<ENUM_CHART_PROPERTY_STRING,string> mapS;  // здесь ошибки компиляции: 'NULL' - cannot convert enum  HashMap.mqh     21      39. 'NULL' - cannot convert enum        HashMap.mqh     462     30

  }

問題はシステム列挙型にあります: ENUM_CHART_PROPERTY_DOUBLE, ENUM_CHART_PROPERTY_STRING 何かがおかしいのです。自作のenumをキータイプにすると、コンパイルも うまくいく。