Предложение - кастинг структур от базовых к производным - страница 2

 
Georgiy Merts:

Я не против полиморфизма, и написал, что если уж так надо - то чем не устраивают классы ?

Тем, что данные обычно хранятся в структурах.  И чтобы передать эту структуру в некий универсальный обработчик, нужно во-первых, создавать обёртку из класса для каждой структуры.  Во-вторых, в процессе копировать структуру в эту обёртку, отправлять класс на обработку, потом копировать изменённую структуру обратно из обёртки.  Это всё затратно и по производительности, и по объёму лишнего кода.  Если можно было бы просто реализовать интерфейсные методы в самой структуре и передавать её по ссылке, ничего не перекопируя.

 
Georgiy Merts:
ну вам никто не мешает использовать их как старые добрые POD типы в своих кодах. тем более что в mql у структур сильно обрезаны возможности по сравнению с классами.
 
Повторюсь, суть в том, что ничего запретного в таком кастинге нет.  Т.к. структуры - это не динамические объекты, то компилятор всегда знает, к какому типу относится тот или иной объект структуры, даже если он передан в функцию с приведением ссылки к базовому типу.  Поэтому ничего не мешает откастить этот объект обратно.
 
Georgiy Merts:

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

в C# для структур и классов распределение памяти разное https://metanit.com/sharp/tutorial/2.16.php
Типы значений и ссылочные типы | C#
  • metanit.com
Ранее мы рассматривали следующие элементарные типы данных: int, byte, double, string, object и др. Также есть сложные типы: структуры, перечисления, классы. Все эти типы данных можно разделить на типы значений, еще называемые значимыми типами, (value types) и ссылочные типы (reference types). Важно понимать между ними различия. Ссылочные типы...
 
Alexey Navoykov:

Если нужно сейчас, то такой обход

#include <TypeToBytes.mqh>

template<typename T>
struct TComparable
{ 
protected: bool Tmp;
public:    int CompareTo(const TComparable & obj) const { return (_C(T, this))._CompareTo(_C(T, obj)); } // OK
// public:    int CompareTo(const TComparable & obj) const { return ((T)this)._CompareTo((T)obj); } // Сейчас тут выдаётся ошибка:  cannot cast 'TComparable<A>' to 'A'
};

template<typename T>
int Compare(const TComparable<T> & a, const TComparable<T> & b)  { return a.CompareTo(b); }


struct A : TComparable<A>
{ 
  double a;
  void operator =(double value) { a=value; }
  int _CompareTo(const A & obj) const { return a>obj.a ? 1 : a<obj.a ? -1 : 0; }
};

void OnInit()
{
  A a=10, b=20;
  
  int result= Compare(a, b);
}


ЗЫ Возможно ли как-то унаследоваться от структуры, чтобы в нее попали только данные базовой структуры - методы/операторы/конструкторы не входили?

 
fxsaber:

Если нужно сейчас, то такой обход

Я работу этого не проверял, но вы уверены, что это то что требуется?   Насколько я понимаю, тут просто создаётся пустой объект производного класса и в него копируются данные базового класса . А смысл? Ведь все исходные данные находятся как-раз таки в производном классе.

Единственное решение сейчас я вижу только через использование внешних winapi-функций для копирования, типа  memcpy.   Но это тоже не универсальный вариант, т.к. придётся заранее импортировать функцию для каждого типа структуры.

 
Alexey Navoykov:

Я работу этого не проверял, но вы уверены, что это то что требуется?   Насколько я понимаю, тут просто создаётся пустой объект производного класса и в него копируются данные базового класса . А смысл? Ведь все исходные данные находятся как-раз таки в производном классе.

Сделал рабочим ваш код. Его смысл должен быть известен автору.

 
fxsaber:

Сделал рабочим ваш код. Его смысл должен быть известен автору.

Т.е. вы хотели сказать: "компилируемым"? )  Ну да, спасибо за труды )   Но можно было и проще:

public:    int CompareTo(const TComparable & obj) const { return 0; } // OK
 
Alexey Navoykov:

Т.е. вы хотели сказать: "компилируемым"? )  Ну да, спасибо за труды )   Но можно было и проще:

Посмотрел код внимательнее. К сожалению, видится бредовым, а-ля "хочу через одно место...": структуру привести к базовой, а потом сделать обратный ход.


Почему это компилируется - вопрос.

struct A : TComparable<A>

Формально наследуем структуру от себя же. Понятно, что в этой конструкции используется уловка для обхода/использования правил компилятора. Но по логике - здесь что-то с чем-то не дружит.

 
fxsaber:

Формально наследуем структуру от себя же. Понятно, что в этой конструкции используется уловка для обхода/использования правил компилятора. Но по логике - здесь что-то с чем-то не дружит.

Никакой уловки, это нормальная конструкция.  Структура не от себя наследуется
Причина обращения: