Вопрос по типизации - страница 4

 
Ilya Malev:

Не очень понятно, в чем проблема. Разве нельзя вынести инициализацию объекта в отдельный метод типа Init(), может даже виртуальный?

Можно, конечно. А разве нельзя сделать class.get_int()/class.get_double()/class.get_string()/... ?)). Стиль, привычка ...

 
pavlick_:

Можно, конечно. А разве нельзя сделать class.get_int()/class.get_double()/class.get_string()/... ?)). Стиль, привычка ...

Можно, только давайте тогда везде, где есть double d, var[]; писать d=var[x].get_double вместо d=var[x]. Если уж заниматься мазохизмом, то коллективно =))

 
Ilya Malev:

То есть в итоге тема сводится к пожеланию ввести в mql возможность перегрузки операции типизации (в т.ч. неявной), то есть определения контекста вызова метода и в зависимости от ожидаемого в данном контексте типа возвращаемого значения вызывать нужный код.

это явно не С++ стандарт будет, да и вообще чем хорош был С++ (его и взяли разработчики MQL за основу) - в С++ все, что не мог программист обработать явно, значит нужно было работать с указателями и прописать свой тип typedef

вот и все, указатель он и в Африке указатель на адрес памяти, его можно всегда передать в качестве параметра и получить как результат ф-ции, разыменовывали указатель - получили физическое значение в памяти байтов, привели указатель к своему новому типу - получили много байтов памяти )))

в MQL указатели сложно сказать зачем, но они есть, разработчики сказали, что приоритет защита данных, поэтому исключены все нововведения, что могут повлечь выходы за "песочницу"



по сабжу, к сожалению я мало имею практики по работе с шаблонами ( template ), но подозреваю, что можно сделать так:

1. написать несколько перегруженных функций, которые в качестве результата возвращают необходимый тип, а в качестве параметра принимают этот тип, т.е. так:

//+------------------------------------------------------------------+
int f(const int x)
  {
   return((int)1);
  };
//+------------------------------------------------------------------+
double f(const double x)
  {
   return((double)2);
  }
//+------------------------------------------------------------------+
string f(const string x)
  {
   return((string)3);
  }
//+------------------------------------------------------------------+
void OnStart()
  { 
   int    a=0;
   double b=0;
   string c="0";
   a = f(a);
   b = f(b);
   c = f(c);
   Print("a = ",a);
   Print("b = ",b);
   Print("c = ",c);
}

2. теперь ф-цию f() нужно обернуть в шаблон и скрыть параметр x - если шаблоны позволяют так делать, тогда вызов будет a=f()  - визуально все будет красиво, типа типизация

 
Igor Makanu:

это явно не С++ стандарт будет

Полагаю, что Вы ошибаетесь - хотя я давно на "чистом" С++ не писал, но в сети полно примеров кода типа этого

class A
{
public:
    operator int()const;
};

A::operator int()const
{
    return 0;
}
 
Ilya Malev:

Полагаю, что Вы ошибаетесь - хотя я давно на "чистом" С++ не писал, но в сети полно примеров кода типа этого

такой пример будет корректно работать, а если сложный тип? - структура или массив? в С++ это и решалось с помощью указателей на свой тип, физически компилятор возвращал адрес памяти, а разыменование указателя обеспечивало корректную работу с данными

 
Igor Makanu:

такой пример будет корректно работать, а если сложный тип? - структура или массив? в С++ это и решалось с помощью указателей на свой тип, физически компилятор возвращал адрес памяти, а разыменование указателя обеспечивало корректную работу с данными

В mql такой пример не будет корректно работать, к сожалению.

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

 
Ilya Malev:

В mql такой пример не будет корректно работать, к сожалению.

ну да, только разглядел, Вы хотите перегрузить преобразование типов, в справке MQL однозначно написано, что разрешается перегрузить, причем унарные операции перегружаются только как унарные и бинарные соответственно, я делал работу с матрицами, пытался перегрузить ^ - не дает, пришлось ! использовать:

  • бинарные +,-,/,*,%,<<,>>,==,!=,<,>,<=,>=,=,+=,-=,/=,*=,%=,&=,|=,^=,<<=,>>=,&&,||,&,|,^;
  • унарные +,-,++,--,!,~;
  • оператор присваивания =;
  • оператор индексации [].


посмотрел еще раз на свой пример - не даст компилятор и мой пример обернуть в template , я же могу возвращать не просто число, а например return((1/x) - а в качестве параметра х могу дать строку string , обычно все Сишные компиляторы на этапе компиляции проверяют соответствие типов, и MQL не дает в шаблоны обернуть неоднозначные решения

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

 
Igor Makanu:

ну да, только разглядел, Вы хотите перегрузить преобразование типов, в справке MQL однозначно написано, что разрешается перегрузить, причем унарные операции перегружаются только как унарные и бинарные соответственно, я делал работу с матрицами, пытался перегрузить ^ - не дает, пришлось ! использовать

Могу утверждать на 99% что нет такой ситуации, где ^ перегрузить не дает, а ! дает. И возможность перегрузки не зависит от типа оператора. Вы что-то не так поняли. Выложите сюда этот пример, хотя если уже забыли и забили, то, конечно не надо )

Единственное ограничение, которое я встретил по типу операторов - это запрет на перегрузку логических операторов ==, !=, ! и = применительно к указателям (any_type * ). Для их корректной перегрузки требуется либо работать с автообъектами, либо со структурами. Просто я в последние месяцы как раз кучу собак на этих фишках съел, поэтому могу говорить уверенно :)

 
Ilya Malev:

Могу утверждать на 99% что нет такой ситуации, где ^ перегрузить не дает, а ! дает. И возможность перегрузки не зависит от типа оператора. Вы что-то не так поняли. Выложите сюда этот пример, хотя если уже забыли и забили, то, конечно не надо )

Единственное ограничение, которое я встретил по типу операторов - это запрет на перегрузку логических операторов ==, !=, ! и = применительно к указателям (any_type * ). Для их корректной перегрузки требуется либо работать с автообъектами, либо со структурами. Просто я в последние месяцы как раз кучу собак на этих фишках съел, поэтому могу говорить уверенно :)

#include <Math\Alglib\linalg.mqh>
class Matrix
  {
public:
   CMatrixDouble     M;
   int               row;//m_strok;
   int               col;//n_stolb;
   void              Matrix(void)         {                             }
   void              Matrix(int m,int n)  { M.Resize(m,n); row=m;col=n; }
   //----      умножение матриц
   Matrix operator*(const Matrix &B){Matrix res(this.row,B.col);CAblas::RMatrixGemm(this.row,B.col,this.col,1.0,this.M,0,0,0,B.M,0,0,0,0,res.M,0,0);return(res);  }
   //----      транспонирование матрицы
   Matrix operator!(void){Matrix res(this.col,this.row);CAblas::RMatrixTranspose(this.row,this.col,this.M,0,0,res.M,0,0);return(res);                             }
   //----      нулевая матрица
   void              zeros(int r,int c) {this.M.Resize(r,c);this.row=r;this.col=c;for(int i=0;i<r;i++){for(int j=0;j<c;j++){this.M[i].Set(j,0.0);}}               }
   //----      вывод в журнал матрицы
   void MatrixPrint(string  separator="|",uint digits=3){string s,sep=" "+separator+" ";for(int i=0;i<row;i++){s=separator;for(int j=0;j<col;j++) s+=DoubleToString(M[i][j],digits)+sep;Print(s);Sleep(123);}}
private:
   void              Matrix(const Matrix &R) { this=R;                                                                                                            }
  };

в "классике" работы с матрицами нужно использовать оператор ^ для транспонирования матриц, вот мой пример - портировал метод SSA из Матлаба, это простейшие умножение, присвоение и транспонирование матриц на основе CMatrixDouble  - он ... такая не знает размеры матриц которые хранит у себя (сколько у него строк и столбцов), пришлось оборачивать в свой класс

 
П.С., а, т.е. Вы хотели перегрузить бинарный оператор как унарный (2-арный как 1-арный), тогда да, конечно не даcт. Единственное исключение - []
Причина обращения: