Biblioteca de classes genéricas - bugs, descrição, perguntas, recursos de uso e sugestões - página 24

 
fxsaber:

Pergunta sobre obter um valor a partir de uma chave. No código da biblioteca, este método parece-se com o seguinte

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

Sim, este código pode ser enganoso devido à mudança de designação não normalizada do i in for.

Primeiro acedemos ao sub-arranjo pelo seu índice, que pode conter o nosso valor:i=m_buckets[hash_code%m_capacity];(i.e. i índice do sub-arranjo ou contentor de valores).

Depois, no mesmo para, o índice do lixo é transformado no índice de itens:i=m_entries[i].next

De facto, o código é escrito correctamente, porque num caso típico cada sub-arranjo terá em média um item e o laço será em média executado apenas uma vez mais.

 
Vasiliy Sokolov:

Sim, este código pode ser enganoso devido à mudança de designação não normalizada do i in for.

Primeiro, acedemos a uma sub-arranjo pelo seu índice, que pode conter o nosso valor:i=m_buckets[hash_code%m_capacity];(i.e. i índice da sub-arranjo ou cesta de valores).

Depois, no mesmo para, o índice do lixo é transformado no índice de itens:i=m_entries[i].next

De facto, o código é escrito correctamente porque num caso típico cada sub-arranjo conterá em média um item e o laço será em média executado apenas uma vez.

Compreendo que o laço é feito para colisões: para percorrer a mini-lista.

 
fxsaber:

Presumo que o laço é feito para colisões: para passar por uma mini-lista.

Sim, absolutamente correcto.

 

Utilizou a biblioteca de modelos(CArrayList) para armazenar tipos personalizados. A impressão não é grande. Para alguma conveniência, escrevi 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)

O excesso de infalibilidade no TryGetValue + impossibilidade de passar classes por valor torna o uso doloroso.

 
Comentários não relacionados com este tópico foram transferidos para "Perguntas dos principiantes do MQL5 MT5 MetaTrader 5".
 

Diga-me, talvez eu não compreenda alguma coisa, mas se eu tentar usar uma construção deste tipo:

#include <Generic\\ArrayList.mqh>

struct Option {
   string name;
   color  clr;
};

...

CArrayList<Option> _options;

Recebo um erro:

Opção' - os objectos são passados apenas por referência ICollection.mqh 14 18

E depois há uma pilha inteira de erros...
 
Andrey Pogoreltsev:

Diga-me, talvez eu não compreenda alguma coisa, mas se eu tentar usar uma construção deste tipo:

Recebo um erro:

Opção' - os objectos são passados apenas por referência ICollection.mqh 14 18

e há uma pilha cheia de erros a seguir...

Experimente desta forma:

#include <Generic\\ArrayList.mqh>

class Option {
   string name;
   color  clr;
};

...

CArrayList<Option*> _options;
 
Sergey Eremin:

Tente desta forma:

Passar/armazenar indicações para uma colecção é conceptualmente errado.

 
Andrey Pogoreltsev:

Passar/armazenar indicações para uma colecção é conceptualmente errado.

não há nenhum genérico para MQL que seja mesmo marginalmente adequado. todos eles têm bugs sérios. use um array inbuilt, isso irá dar-lhe menos dores de cabeça.

 
TheXpert:

não há nenhum genérico para MQL que seja mesmo ligeiramente adequado. todos eles têm bugs graves. use uma matriz embutida, isso irá dar-lhe menos dores de cabeça.

Bem, sim, já usei uma matriz. Porquê criar colecções e colocá-las em kodobase se só são adequadas para tipos incorporados?)