Библиотека Generic классов - ошибки, описание, вопросы, особенности использования и предложения - страница 24

 
fxsaber:

Вопрос о получении значения по ключу. В коде библиотеки этот метод выглядит так

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

Да, этот код может ввести в заблуждение из-за нестандартного переназначения i в for.

Сначала мы обращаемся к подмассиву по его индексу, который может содержать наше значение:  i=m_buckets[hash_code%m_capacity]; (т.е. i индекс подмассива или корзины значений).

Затем в этом же for индекс корзины превращается в индекс элементов корзины: i=m_entries[i].next 

В действительности код написан верно, т.к. в типичном случае в каждом подмассиве будет в среднем один елемент и цикл опять-таки в среднем будет выполнится лишь единожды.

 
Vasiliy Sokolov:

Да, этот код может ввести в заблуждение из-за нестандартного переназначения i в for.

Сначала мы обращаемся к подмассиву по его индексу, который может содержать наше значение:  i=m_buckets[hash_code%m_capacity]; (т.е. i индекс подмассива или корзины значений).

Затем в этом же for индекс корзины превращается в индекс элементов корзины: i=m_entries[i].next 

В действительности код написан верно, т.к. в типичном случае в каждом подмассиве будет в среднем один елемент и цикл опять-таки в среднем будет выполнится лишь единожды.

Понял так, что цикл сделан на случай коллизий: пройтись по мини-списку.

 
fxsaber:

Понял так, что цикл сделан на случай коллизий: пройтись по мини-списку.

Да, совершенно верно. 

 

Попользовался шаблонной библиотекой (CArrayList) для хранения пользовательских типов. Впечатление - не в восторге. Для хоть какого-то удобство писал макросы

#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)

Излишняя защита от дурака в TryGetValue + невозможность передать классы по значению делают использование мучительным.

 
Комментарии, не относящиеся к этой теме, были перенесены в "Вопросы от начинающих MQL5 MT5 MetaTrader 5".
 

Скажите, может я чего не понимаю, но если пытаюсь использовать конструкцию такого типа:

#include <Generic\\ArrayList.mqh>

struct Option {
   string name;
   color  clr;
};

...

CArrayList<Option> _options;

то ловлю ошибку:

'Option' - objects are passed by reference only ICollection.mqh 14 18

ну и там полный стэк ошибок дальше...
 
Andrey Pogoreltsev:

Скажите, может я чего не понимаю, но если пытаюсь использовать конструкцию такого типа:

то ловлю ошибку:

'Option' - objects are passed by reference only ICollection.mqh 14 18

ну и там полный стэк ошибок дальше...

Попробуйте так:

#include <Generic\\ArrayList.mqh>

class Option {
   string name;
   color  clr;
};

...

CArrayList<Option*> _options;
 
Sergey Eremin:

Попробуйте так:

Передавать/хранить указатели в коллекцию неверно концептуально.

 
Andrey Pogoreltsev:

Передавать/хранить указатели в коллекцию неверно концептуально.

нету под MQL ни одного хотя бы мало мальски пригодного дженерика. у всех есть серьезные косяки. пользуйте встроенный массив, меньше голова болеть будет

 
TheXpert:

нету под MQL ни одного хотя бы мало мальски пригодного дженерика. у всех есть серьезные косяки. пользуйте встроенный массив, меньше голова болеть будет

ну так то да, массив заюзал. Просто зачем создавать коллекции и выкладывать их в кодобазу если они годятся только для встроенных типов?)

Причина обращения: