Biblioteca de clases genéricas - errores, descripción, preguntas, características de uso y sugerencias - página 24

 
fxsaber:

Pregunta sobre cómo obtener un valor de una clave. En el código de la biblioteca, este método tiene el siguiente aspecto

//+------------------------------------------------------------------+
//| 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);
  }

Sí, este código puede ser engañoso debido a la reasignación no estándar de i en for.

Primero accedemos a la submatriz por su índice, que puede contener nuestro valor:i=m_buckets[hash_code%m_capacity];(es decir, índice i de la submatriz o bin de valores).

A continuación, en el mismo for, el índice de la bandeja se convierte en el índice del elemento de la bandeja:i=m_entries[i].next

De hecho, el código está escrito correctamente, porque en un caso típico cada submatriz tendrá de media un elemento y el bucle se ejecutará de media sólo una vez.

 
Vasiliy Sokolov:

Sí, este código puede ser engañoso debido a la reasignación no estándar de i en for.

En primer lugar, accedemos a una submatriz por su índice, que puede contener nuestro valor:i=m_buckets[hash_code%m_capacity];(es decir, el índice i de la submatriz o cesta de valores).

A continuación, en el mismo for, el índice de la bandeja se convierte en el índice del elemento de la bandeja:i=m_entries[i].next

De hecho, el código está escrito correctamente porque en un caso típico cada submatriz contendrá de media un elemento y el bucle se ejecutará de media sólo una vez.

Entiendo que el bucle está hecho para las colisiones: para recorrer la minilista.

 
fxsaber:

Entiendo que el bucle está hecho para las colisiones: para recorrer una minilista.

Sí, absolutamente cierto.

 

Utilizar la biblioteca de plantillas(CArrayList) para almacenar tipos personalizados. La impresión no es muy buena. Para mayor comodidad, he escrito 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)

El exceso de pruebas en TryGetValue + la imposibilidad de pasar clases por valor hace que su uso sea doloroso.

 
Los comentarios no relacionados con este tema han sido trasladados a "Preguntas de los principiantes de MQL5 MT5 MetaTrader 5".
 

Dígame, tal vez no entiendo algo, pero si trato de usar una construcción de este tipo:

#include <Generic\\ArrayList.mqh>

struct Option {
   string name;
   color  clr;
};

...

CArrayList<Option> _options;

Me da un error:

'Opción' - los objetos se pasan sólo por referencia ICollection.mqh 14 18

Y luego hay toda una pila de errores...
 
Andrey Pogoreltsev:

Dígame, tal vez no entiendo algo, pero si trato de usar una construcción de este tipo:

Me da un error:

'Opción' - los objetos se pasan sólo por referencia ICollection.mqh 14 18

y hay una pila completa de errores a continuación...

Pruébalo así:

#include <Generic\\ArrayList.mqh>

class Option {
   string name;
   color  clr;
};

...

CArrayList<Option*> _options;
 
Sergey Eremin:

Inténtalo de esta manera:

Pasar/almacenar punteros a una colección es un error conceptual.

 
Andrey Pogoreltsev:

Pasar/almacenar punteros a una colección es un error conceptual.

no hay ningún genérico para MQL que sea mínimamente adecuado. todos ellos tienen serios errores. utilice una matriz incorporada, le dará menos dolor de cabeza.

 
TheXpert:

no hay ningún genérico para MQL que sea mínimamente adecuado. todos ellos tienen serios errores. usa un array embebido, te dará menos dolores de cabeza.

Bueno, sí, he utilizado una matriz. ¿Por qué crear colecciones y ponerlas en kodobase si sólo sirven para los tipos incorporados)?