Как одним оператором сравнить две простых структуры ?

 

Всех приветствую.

Вопрос - в заголовке. Простые структуры можно копировать одним оператором равенства. А сравнить - не выходит. Приходится сравнивать каждое поле. Теряется универсальность.

Кто-нибудь пытался сделать универсальное сравнение простых структур ? Хочется обойтись без хаков типа memcmp, или внешних ДЛЛ.

Что предложите, коллеги ?



С чего возник вопрос. Пишу универсальный класс-шаблон контейнера структур (что-то типа обертки над структурой, чтобы можно было работать с любой структурой, как с классом - получать указатель, складывать структуры в CArrayObj и т д):

template<typename T> class CStructContainerT

Чтобы можно было объявить что-то вроде:

CStructContainerT<MqlTick> 

И получить готовый объект на основе структуры (в данном случае - на основе MqlTick).

Вот, уперся в функцию сравнения. Обязательно понадобится функция, которая бы могла сравнивать два объекта-контейнера одного типа, а универсальной ее сделать не получается. Ничего не могу придумать - только написания специальной функции сравнения для каждой новой структуры... Однако, в этом случае вобще теряется смысл в таком контейнере.

 
George Merts:

Вопрос - в заголовке. Простые структуры можно копировать одним оператором равенства. А сравнить - не выходит. Приходится сравнивать каждое поле. Теряется универсальность.

#include <TypeToBytes.mqh>

void OnStart()
{
  MqlTick Tick1, Tick2;
//  MqlTick Tick1[], Tick2[]; //  можно и так и много еще как
  
  if (_R(Tick1) == Tick2)
    Print("Equal!");
}
 

fxsaber перегонял в байты, наверное в кодобазе есть.

Как по мне православный путь -- иметь явно написанный оператор сравнения для каждой структуры где это нужно.

 
Комбинатор:

fxsaber перегонял в байты, наверное в кодобазе есть.

Как по мне православный путь -- иметь явно написанный оператор сравнения для каждой структуры где это нужно.

Дык вот же, и мне тоже так кажется... Но, хочется универсальности.

fxsaber, спасибо, сейчас погляжу твой вариант...

P.S.

Да ! Точно, fxsaber, то, что нужно. Еще раз благодарю.

 

"TypeToBytes.mqh" - это что?  Я не нашёл такого файла у себя.

В любом случае, всё делается очень просто вот так:

template<typename T>
int StructCompare(const T& obj1, const T& obj2)
{
  static T array[2];
  array[0]= obj1;
  array[1]= obj2;
  return ArrayCompare(array, array, 0, 1, 1);
}
Хотя конечно это медленный вариант. Можно обойтись и без копирования, а лишь приведением, но на начальном этапе и это сгодится )
 
Alexey Navoykov:

"TypeToBytes.mqh" - это что?  Я не нашёл такого файла у себя.

В любом случае, всё делается очень просто вот так:

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

Хм... Тоже интересный вариант. Рассмотрю.

TypeToBytes.mqh - это библиотека fxsaber'a. В Кодобазе есть.

 

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

А вот в прежних билдах прекрасно работает такой вариант:

template<typename T>
int StructCompare(const T& obj1, const T& obj2)
{
  struct TT
  {
    T array[1];
  };
  return ArrayCompare(((TT)obj1).array, ((TT)obj2).array);
}
 
Есть вариант для каждого объекта/структуры после его/её изменения считать сигнатуру - аналог hashCode в объектах java. Тогда сравнивать нужно будет только хэши - как ulong например.
 

Да, мне очень даже подошел вариант с ArrayCompare - все получилось.

В объекте-обертке я использую не просто T (параметр шаблона), а массив T[1] из одного элемента. И там, где надо сравнить - использую сравнение массивов.

Вариант с объявлением внутренней структуры TT - мне кажется, не вполне "православный" - действительно, приведение структуры выглядит, по-моему, не совсем правильно.

Вариант, как у fxsabera, с перегоном в байты - интересный, но в моем случае, требует больше переделок (а просто подключать библиотеку - мне не хотелось бы).

 
George Merts:

Вариант, как у fxsabera, с перегоном в байты - интересный, но в моем случае, требует больше переделок (а просто подключать библиотеку - мне не хотелось бы).

Как вариант, выдрать из библы только нужный кусок идеи. Это, наверное, самый простой функционал. Все же с операторами при сравнении работать нагляднее.
 
fxsaber:
Как вариант, выдрать из библы только нужный кусок идеи. Это, наверное, самый простой функционал. Все же с операторами при сравнении работать нагляднее.

Ну, я так обычно и делаю. И из твоего кода - у меня довольно много фрагментов используется.

Безусловно, с операторами сравнения работать - намного удобнее. Но, в данном случае, мне этот оператор требуется исключительно внутри этой обертки, чтобы структуры "сами" отличали друг друга. Поэтому мне кажется разумнее - использование "массива" из одного элемента и функция ArrayCompare.

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