std::vector<T>::iterator, оптимальное названия макроса по разыменовыванию итераторов в MQL (детали в первом посте)

 
  • 6% (3)
  • 2% (1)
  • 13% (7)
  • 4% (2)
  • 38% (20)
  • 2% (1)
  • 35% (18)
Всего проголосовало: 52
 

Наверно, многие из нас, по крайней мере те, кто знаком с С++, мечтали о импорте STL (Standard Template Library) в MQL.
И, к сожалению, многие годы это было действительно невозможно.
Но, благодаря всем нам, а особенно - разработчикам, MQL не просто жив, а медленно но уверенно развивается...
И то, что раньше было только в мечтах, сегодня уже готовится чтобы сделать свои первые шаги на пути к обыденности.


А если серьезно, кроме хвастовства современными возможностями MQL, хочу попросить помощи по решению дилеммы выбора оптимального названия макроса по разыменовыванию итераторов в MQL.
В нижеприведенном "псевдокоде", при доступе к контейнеру по индексу возвращает указатель, а не помещенное значение.
Для получения значения, указатель дополнительно необходимо разыменовывать, для этого используется макрос.
Все наведенные в коде макросы: iterator.GET, iterator.VALUE, iterator.UNREF, iterator.DATA_(iterator) - выполняют одно и то же действие и являются взаимозаменяемыми.
Прошу выбрать из предложенного списка, на ваш вкус и цвет максимально понятный и удобный макрос по разыменовыванию итераторов в MQL.

Спасибо.

// StructA/ClassA
struct StructA{
   uchar data;
};

void OnStart(){
   int value_int = 1;
   ClassA value_class_ptr(2);
   ClassA* value_ptr = &value_class_ptr;
   ClassA value_class(3);
   StructA value_struct = {4};

   vector<int>      v_int(5);
   vector<ClassA*>  v_ptr(5);
   vector<ClassA>   v_class(5);
   vector<StructA>  v_struct(5);
   
   
   PRINT("Test direct value assigning");
   v_int[0].GET = value_int;
   v_ptr[0].VALUE = value_ptr;
   v_class[0].UNREF = value_class;
   v_struct[0].DATA = value_struct;
   
   PRINT(v_int[0].DATA == value_int);
   PRINT(v_ptr[0].GET.data == value_ptr.data);
   PRINT(v_class[0].VALUE.data == value_class.data);
   PRINT(v_struct[0].UNREF.data == value_struct.data);
   
   
   PRINT("Test pass by ref");
   //void init_value(_Tp &dst, _Tp &src){dst = src;}
   init_value(v_int[1].UNREF, value_int);
   init_value(v_ptr[1].DATA, value_ptr);
   init_value(v_class[1].GET, value_class);
   init_value(v_struct[1].VALUE, value_struct);
   
   PRINT(_(v_int[1]) == value_int);
   PRINT(_(v_ptr[1]).data == value_class_ptr.data);
   PRINT(_(v_class[1]).data == value_class.data);
   PRINT(_(v_struct[1]).data == value_struct.data);
   
   
   PRINT("Test iterators");
   int n = 0;
   for(vector<int>::iterator it = v_int.begin(); it != v_int.end(); ++it){
      it.DATA = n++;
   }
   
   LAMBDA_CREATE_P1(void, my_print, int &x, {
      PRINT(x);  
   });
   
   for_each(v_int.begin(), v_int.end(), LAMBDA_FUNC(my_print));   //0, 1, 2, 3, 4
}

template<typename InputIterator, typename Function>
void for_each(InputIterator &first, InputIterator &last, Function fn){
  while (first!=last) {
    fn(first.UNREF);
    ++first;
  }
}
 
Sergey Dzyublik:

Наверно, многие из нас, по крайней мере те, кто знаком с С++, мечтали о импорте STL (Standard Template Library) в MQL.
И, к сожалению, многие годы это было действительно невозможно.
Но, благодаря всем нам, а особенно - разработчикам, MQL не просто жив, а медленно но уверенно развивается...
И то, что раньше было только в мечтах, сегодня уже готовится чтобы сделать свои первые шаги на пути к обыденности.


А если серьезно, кроме хвастовства современными возможностями MQL, хочу попросить помощи по решению дилеммы выбора оптимального названия макроса по разыменовыванию итераторов в MQL.
В нижеприведенном "псевдокоде", при доступе к контейнеру по индексу возвращает указатель, а не помещенное значение.
Для получения значения, указатель дополнительно необходимо разыменовывать, для этого используется макрос.
Все наведенные в коде макросы: GET, VALUE, UNREF, DATA - выполняют одно и то же действие и являются взаимозаменяемыми.
Прошу выбрать из предложенного списка, на ваш вкус и цвет максимально понятный и удобный макрос по разыменовыванию итераторов в MQL.
Спасибо.

#define _(dPtr) dPtr.Get()
#define __(dPtr) _(dPtr).Get()
и т.д.

Дарю.

PS. Портировать один в один не получится. Сам это пилю. Скоро, может быть, выложу.

 
Vladimir Simakov:

Дарю.

Спасибо за столь щедрое великодушие.
Не совсем уверен в удобочитаемости предложенного варианта, но он явно ближе к стилистике С++ и в этом свой плюс.
Так что имеет место быть, использование #define _(dPtr) добавлено в  код для общего сравнения.

 

Можно объединить оба вышеприведённых варианта )

ptr._.method()


Либо можно ещё перегрузить оператор --

Будет в таком виде:

ptr--.method()

Хотя это конечно тоже может создавать путаницу.

 

deref, lvalue.

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

Круто конечно, но это очень похоже на хитрые хаки для решения (теперь) банальных проблем в самом начале mql4.

Но само решение все равно интересно ) будет код макроса и контейнера?
 

В своей библиотеке я делал так:

  for(Iterator<double> *id = numbers.begin(); *id != *end; ++id)
  {
    id = ~id + 1; // '~' used for dereference instead of unavailable '*'
  }
Но иногда нужны скобки из-за приоритета ~.
 
Stanislav Korotky:

В своей библиотеке я делал так:

не, это понятно. любой тип оборачивается в обертку для появления указателя?

со ссылками и оператором приведения типа можно было бы обойтись без разыменования вообще.

 
Ууу... опять лыжи наизнанку одели!
 
TheXpert:

не, это понятно. любой тип оборачивается в обертку для появления указателя?

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

 
TheXpert:

не, это понятно. любой тип оборачивается в обертку для появления указателя?

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


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