Cuestión de mecanografía - página 4

 
Ilya Malev:

No está muy claro cuál es el problema. ¿No podría colocarse la inicialización del objeto en un método separado como Init(), tal vez incluso uno virtual?

Sí, por supuesto. No se puede class.get_int()/class.get_double()/class.get_string()/... ?)). Estilo, hábito...

 
pavlick_:

Claro que sí. No se ha podido class.get_int()/class.get_double()/class.get_string()/. ?)). Estilo, hábito...

Podemos, pero escribamos d=var[x].get_double en lugar de d=var[x] siempre que haya doble d, var[];. Si vamos a hacer masoquismo, deberíamos hacerlo colectivamente =))

 
Ilya Malev:

Por lo tanto, al final se reduce al deseo de introducir en mql la capacidad de sobrecargar la operación de tipificación (incluso implícita), es decir, definir un contexto de llamada a un método y en función de lo esperado en este contexto devolver el tipo de valor para llamar al código requerido.

Obviamente esto no es un estándar de C++, y en general, lo bueno de C++ (y que fue tomado por los desarrolladores de MQL como base) es que todo lo que en C++ el programador no podía manejar explícitamente, tenía que trabajar con los punteros y escribir su tipotypedef

un puntero es sólo un puntero a una dirección de memoria, siempre puedes pasarlo como parámetro y obtenerlo como resultado de una función, desreferenciar un puntero te da un valor físico en bytes de memoria, convertir un puntero a su nuevo tipo te da muchos bytes de memoria ))))

En MQL, los punteros son difíciles de decir por qué, pero están ahí, los desarrolladores dijeron que la prioridad es la protección de datos, por lo que se excluyen todas las innovaciones que podrían conducir a salidas de la caja de arena



sobre el tema, lamentablemente tengo poca práctica trabajando con plantillas ( template ), pero sospecho que se puede hacer:

1. escribir algunas funciones sobrecargadas que devuelvan el tipo requerido como resultado, y que tomen ese tipo como parámetro, es decir, así:

//+------------------------------------------------------------------+
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. ahora la función f() necesita ser envuelta en una plantilla y ocultar el parámetro x - si las plantillas lo permiten, entonces la llamada será a=f() - visualmente todo será bonito, como escribir

 
Igor Makanu:

obviamente no es un estándar C++

Creo que te equivocas - aunque hace tiempo que no escribo en C++ "puro", hay muchos ejemplos de código como este en la web

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

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

Creo que te equivocas - aunque hace tiempo que no escribo en C++ "puro", pero la web está llena de ejemplos de código como este

¿Pero qué pasa si es un tipo complejo? - ¿Una estructura o un array? En C++ esto se solucionaba utilizando punteros a su tipo, físicamente el compilador devolvía la dirección de memoria y al desreferenciar el puntero se aseguraba que los datos se manejaban correctamente

 
Igor Makanu:

Este ejemplo funcionaría correctamente, pero ¿qué pasa si se trata de un tipo complejo? - En C++ esto se resolvía con punteros a su tipo, físicamente el compilador devolvía la dirección de memoria y la desreferenciación del puntero proporcionaba el manejo correcto de los datos

Este ejemplo no funcionaría correctamente en mql, por desgracia.

Un tipo complejo, una estructura o un array pueden sobrecargar lo que necesiten, no requieren una sobrecarga de conversión de tipos...

 
Ilya Malev:

En mql tal ejemplo no funcionaría correctamente, por desgracia.

¡Bueno, sí, acabo de ver, quieres sobrecargar la conversión de tipos, la ayuda de MQL dice claramente que está permitido sobrecargar, y las operaciones unarias se sobrecargan sólo como unarias y binarias, respectivamente, estaba trabajando con matrices, traté de sobrecargar ^ - no funciona, tuve que usar !

  • бинарные +,-,/,*,%,<<,>>,==,!=,<,>,<=,>=,=,+=,-=,/=,*=,%=,&=,|=,^=,<<=,>>=,&&,||,&,|,^;
  • unario +,-,++,--,~;
  • operador de asignación =;
  • operador de indexación [].


He vuelto a mirar mi ejemplo - el compilador no permite envolver mi ejemplo enuna plantilla. Puedo devolver((1/x) - y puedo dar una cadena de caracteres como parámetro x. Normalmente todos los compiladores de C comprueban la coincidencia de tipos en tiempo de compilación, y MQL no permite envolver soluciones ambiguas en plantillas.

imho, su problema - post 1 del tema, en MQL puede ser resuelto correctamente, sólo mediante la descripción de todas lasfunciones sobrecargadas. A continuación, todos los tipos de variables que se pasan y devuelven y todas las funciones sobrecargadas se comprobarán en tiempo de compilación.

 
Igor Makanu:

¡Sí, acabo de ver, usted quiere sobrecargar la conversión de tipos, la ayuda MQL dice claramente que la sobrecarga está permitida, y las operaciones unarias se sobrecargan sólo como unario y binario, respectivamente, yo estaba trabajando con matrices, trató de sobrecargar ^ - no funciona, tuve que usar !

¡Puedo afirmar en un 99% que no existe tal situación en la que ^ no pueda sobrecargarse, mientras que ! Y la capacidad de sobrecarga no depende del tipo de operador. Debes haber entendido algo mal. Sólo hay que poner este ejemplo aquí, pero si ya lo has olvidado y te has dado por vencido, por supuesto que no lo hagas).

La única restricción que he encontrado con respecto a los tipos de operadores es la prohibición de sobrecargar los operadores lógicos ==, !=, ! y = aplicados a los punteros (any_type * ). Para sobrecargarlos correctamente es necesario trabajar con objetos automáticos o con estructuras. Sólo en los últimos meses he comido muchos perros en estas cosas, así que puedo hablar con confianza :)

 
Ilya Malev:

¡Puedo decir en un 99% que no hay ninguna situación en la que ^ no se sobrecargue, pero sí ! Y la capacidad de sobrecarga no depende del tipo de operador. Debes haber entendido algo mal. Sólo hay que poner este ejemplo aquí, pero si ya lo has olvidado y te olvidas de él, mejor no lo hagas).

La única restricción que he encontrado con respecto a los tipos de operadores es la prohibición de sobrecargar los operadores lógicos ==, !=, ! y = aplicados a los punteros (any_type * ). Para sobrecargarlos correctamente es necesario trabajar con objetos automáticos o con estructuras. En los últimos meses he comido muchos de estos trucos, así que puedo decir con confianza :)

#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;                                                                                                            }
  };

En el manejo "clásico" de las matrices es necesario utilizar el operador ^ para transponer las matrices, aquí está mi ejemplo - porté el método SSA de Matlab, es la más simple multiplicación, asignación y transposición de matrices basadas en CMatrixDouble - es ... no sabe el tamaño de las matrices que almacena (cuántas filas y columnas tiene).

 
P.D., ah, es decir, querías sobrecargar un operador binario como uno unario (2ar como 1ar), entonces sí, por supuesto que no. La única excepción es []