Bibliothèque de classes génériques - bogues, description, questions, caractéristiques d'utilisation et suggestions - page 24

 
fxsaber:

Question sur l'obtention d'une valeur à partir d'une clé. Dans le code de la bibliothèque, cette méthode ressemble à ceci

//+------------------------------------------------------------------+
//| Find index of entry with specified key.                          |
//+------------------------------------------------------------------+
template<typename TKey,typename TValue>
int CHashMap::FindEntry(TKey key)
  {
   if(m_capacity!=NULL)
     {
      //--- get hash code from key
      int hash_code=m_comparer.HashCode(key)&0x7FFFFFFF;
      //--- search pair with specified key
      for(int i=m_buckets[hash_code%m_capacity]; i>=0; i=m_entries[i].next)
         if(m_entries[i].hash_code==hash_code && m_comparer.Equals(m_entries[i].key,key))
            return(i);
     }
   return(-1);
  }

Oui, ce code peut être trompeur en raison de la réaffectation non standard de i dans for.

Tout d'abord, nous accédons au sous-réseau par son index, qui peut contenir notre valeur :i=m_buckets[hash_code%m_capacity] ;(c'est-à-dire l'index i du sous-réseau ou du bac de valeur).

Ensuite, dans le même for, l'index du bac est transformé en index de l'élément du bac :i=m_entries[i].next

En fait, le code est écrit correctement, car dans un cas typique, chaque sous-réseau aura en moyenne un élément et la boucle ne sera en moyenne exécutée qu'une seule fois.

 
Vasiliy Sokolov:

Oui, ce code peut être trompeur en raison de la réaffectation non standard de i dans for.

Tout d'abord, nous accédons à un sous-réseau par son index, qui peut contenir notre valeur :i=m_buckets[hash_code%m_capacity] ;(c'est-à-dire i index du sous-réseau ou panier de valeurs).

Ensuite, dans le même for, l'index du bac est transformé en index de l'élément du bac :i=m_entries[i].next

En fait, le code est écrit correctement car, dans un cas typique, chaque sous-réseau contient en moyenne un élément et la boucle ne s'exécute en moyenne qu'une seule fois.

Je comprends que la boucle est faite pour les collisions : passer par la mini-liste.

 
fxsaber:

J'en déduis que la boucle est faite pour les collisions : pour parcourir une mini-liste.

Oui, tout à fait.

 

Utilisation de la bibliothèque de modèles(CArrayList) pour stocker les types personnalisés. L'impression n'est pas très bonne. Pour des raisons de commodité, j'ai écrit des macros

#define  CLEANUP   do {                                      \
   for(int i_cln = 0;  i_cln < segs.Count();  ++ i_cln) {   \
      Wave_end *cln_el;                                     \
      if(  segs.TryGetValue(i_cln, cln_el) )                \
         delete cln_el;                                     \
   }}while(false)
#define  SSEG(IND)  do {                \
if( ! segs.TryGetValue(IND, we) ) {    \
   CLEANUP;                            \
   continue;                           \
}}while(false)

L'excès de foolproofing dans TryGetValue + l'impossibilité de passer des classes par valeur rend l'utilisation pénible.

 
Les commentaires non liés à ce sujet ont été déplacés vers "Questions des débutants de MQL5 MT5 MetaTrader 5".
 

Dites-moi, peut-être que je ne comprends pas quelque chose, mais si j'essaie d'utiliser une construction de ce type :

#include <Generic\\ArrayList.mqh>

struct Option {
   string name;
   color  clr;
};

...

CArrayList<Option> _options;

Je reçois une erreur :

Option - les objets sont transmis uniquement par référence ICollection.mqh 14 18

Et puis il y a toute une série d'erreurs...
 
Andrey Pogoreltsev:

Dites-moi, peut-être que je ne comprends pas quelque chose, mais si j'essaie d'utiliser une construction de ce type :

Je reçois une erreur :

Option - les objets sont transmis uniquement par référence ICollection.mqh 14 18

et il y a une pile complète d'erreurs ensuite...

Essayez comme ça :

#include <Generic\\ArrayList.mqh>

class Option {
   string name;
   color  clr;
};

...

CArrayList<Option*> _options;
 
Sergey Eremin:

Essayez de cette façon :

Passer/stocker des pointeurs vers une collection est une erreur conceptuelle.

 
Andrey Pogoreltsev:

Passer/stocker des pointeurs vers une collection est une erreur conceptuelle.

il n'y a pas de générique pour MQL qui soit même marginalement approprié. tous ont de sérieux bugs. utilisez un tableau intégré, cela vous donnera moins de maux de tête.

 
TheXpert:

il n'y a pas de générique pour MQL qui soit un tant soit peu approprié. tous ont de sérieux bugs. utilisez un tableau intégré, cela vous donnera moins de maux de tête.

Eh bien, oui, j'ai utilisé un tableau. Pourquoi créer des collections et les mettre dans kodobase si elles ne conviennent qu'aux types intégrés) ?

Raison: