Error del compilador con el parámetro de la plantilla = void* - página 7

 
Alexey Navoykov:

Yo lo habría hecho así:

Este estilo me resulta incómodo. Es decir, se trata de "rotuladores".

 
fxsaber:

¿Así que también quieres advertencias? ¿Qué es este doble rasero: en ambos sitios el comportamiento es inequívoco, pero con los paréntesis estás en contra de las advertencias y aquí estás a favor?

Necesitas una advertencia para no cometer errores difíciles de encontrar. Así que la dificultad es una evaluación subjetiva. Así que con los corchetes no te equivocas, y aquí sí. Y para mí es viceversa.

Entonces, ¿a cuál de los dos hay que ajustar las normas de emisión de avisos?

Parece que no entiendes el punto. El casting dinámico debe ser siempre una operación explícita. En cualquier lenguaje normal, ya sea C++, C#, Java o cualquier otro lenguaje OOP, ese código no compila. Esta es la base de la POO fiable. Pero se olvidó aquí por alguna razón. No me pareció que la comparación del paréntesis fuera apropiada aquí en absoluto.

 
Alexey Navoykov:

La base de los fundamentos de una OOP fiable.

La base en la falta de ambigüedad.

 
Ilya Malev:

No veo el sentido del código de referencia (aunque tampoco uso bibliotecas estándar). Si poner un objeto en un array implica crear una copia del mismo, entonces el método de asignación o el constructor de la copia deben ser declarados y descritos explícitamente en esta clase, de lo contrario ninguna envoltura servirá de todos modos. Si sólo necesitas poner una referencia a un objeto en un array, no necesitas ninguna envoltura (¿por qué?).

¿Para qué necesitas una matriz así? Como es casi análogo a un vector plus, debería funcionar como vector<int>, vector<nombre_clase>, vector<nombre_clase*>. Si puedes implementarlo sin envolver por medio de µl, bien por ti (no creo que puedas). No tiene la capacidad de recorrer un array y llamar a destructores ( _data[i].~Destr() ), ni especialización parcial ni trucos de SFINAE. Esta envoltura hace que el array sea apto para punteros a objetos en el heap sin romper la posibilidad de trabajar con vector<int>, por ejemplo.

vector<unique_ptr<my_class>> v1;

vector<my_class> v2;

vector<int> v3;

ZS: qué decir, vector<nombre_de_clase*> no funcionará como se espera incluso en los pluses (llamada al destructor al final de la vida del vector) también hay que envolver.
 
pavlick_:

ZS: que decir, vector<nombre_de_clase*> no funcionará como se espera incluso en los pluses (llamada al destructor al final de la vida del vector) necesita envoltura también.

¿Funcionará? )

template<typename T>
void del(T par){printf("%s не удаляем",typename(T));}

template<typename T>
void del(T *par){printf("%s удаляем",typename(T));delete par;}

class A{public:void~A(void){printf("удаляем %i",&this);}};

void OnStart()
 {
  int var1;
  A *var2=new A;
  del(var1);
  del(var2);
 }

P.D. Por analogía, una función puede devolver cualquier cosa en lugar de void, y no se necesita SFINAE.

 
Sí, está bien. Pero todavía necesitamos una envoltura: necesitamos un array universal, por lo que a veces tiene punteros que necesitan ser eliminados, y otras veces no (bueno, sólo un conjunto de punteros - el resultado de encontrar algo en otro array).
 
pavlick_:

En el lado positivo, la eliminación de void* es UB.

Por cierto, no lo había pensado antes, gracias por el consejo. Resulta que delete en este caso es similar a free(). Debería estar prohibido, ya que delete está posicionado para objetos y simplemente libera memoria saltándose las reglas.

Aunque los destructores son llamados aquí también, pero en caso de portar el código a C++ uno puede encontrar problemas.

 
pavlick_:
Sí, eso servirá. Pero todavía necesitamos envolver: después de todo, necesitamos un array universal, por lo que a veces tiene punteros que necesitan hacer la eliminación, y otras veces no (bueno, sólo un montón de punteros - el resultado de encontrar algo en otro array).

Bueno, nadie prohíbe pasar una opción adicional al crear un array - si se borran los elementos al borrarlo o no, y hacer que esté activada o desactivada por defecto (a tu gusto). Al fin y al cabo, nunca se puede adivinar si se quieren borrar elementos o no)).

P.D. Por cierto, envolver un puntero antes de ponerlo en un array no resuelve la cuestión de si es necesario o no borrar su objeto base al borrar el array))
 
fxsaber:

Los corchetes adicionales han eliminado por completo la influencia de las prioridades lingüísticas. Todo se vuelve completamente inequívoco. Esto hace que sea 100% fiable que nada se rompa después de la siguiente construcción.

Teniendo esto en cuenta, resumiré:


A100
Desarrolladores
fxsaber
soportes
sólo en lugares donde son indispensables
tal vez incluso en lugares donde MQL4 era diferente antes
se necesitan en todas partes
advertencias innecesarias
no es necesario
sólo en los lugares donde MQL4 era diferente antes
se necesita en todas partes
prioridades
es necesario
requerido
en principio no es necesario (porque los corchetes los sustituyen)

Si no lo he expresado correctamente - por favor, corríjanme - he hecho mi concepto corto y sin ambigüedades donde las advertencias sobre los paréntesis son necesarias

 
Ilya Malev:

Bueno, nadie prohíbe pasar una opción adicional al crear un array - si se borran los elementos al borrarlo o no, y hacer que esté activada o desactivada por defecto (a tu gusto). Porque es difícil de adivinar, si debe eliminar elementos o no)).

En general, sí, se puede hacer así.

P.D. Por cierto, el hecho de envolver un puntero antes de meterlo en un array, no aclara la cuestión de si hay que borrar su objeto base o no al borrar el array))


Si no lo envuelves, no lo borras, si lo envuelves, lo borras, está clarísimo.

ZS: pero si lo hiciera, lo haría lo más parecido posible a la biblioteca estándar plus (nombres, comportamiento, etc.), así que no hay opción para mí. ¿Por qué molestarse en crear otra especificación cuando todo está ya escrito?