Compilerfehler mit Template-Parameter = void* - Seite 7

 
Alexey Navoykov:

Ich hätte es so gemacht:

Ich finde diesen Stil unangenehm. Das heißt, es geht um "Filzstifte".

 
fxsaber:

Sie wollen also auch Warnungen? Was ist das für eine Doppelmoral: An beiden Stellen ist das Verhalten eindeutig, aber bei Klammern sind Sie gegen Verwarnungen und hier sind Sie dafür?

Sie brauchen eine Warnung, damit Sie keine schwer zu findenden Fehler machen. Die Schwierigkeit ist also eine subjektive Einschätzung. Bei Klammern macht man keine Fehler, aber hier schon. Und bei mir ist es umgekehrt.

An wen von uns sollten also die Regeln für die Erteilung von Verwarnungen angepasst werden?

Sie scheinen nicht zu verstehen, worum es geht: Dynamisches Casting muss immer eine explizite Operation sein. In jeder normalen Sprache, sei es C++, C#, Java oder eine andere OOP-Sprache, wird solcher Code nicht kompiliert. Dies ist die Grundlage einer zuverlässigen OOP. Aber aus irgendeinem Grund wurde es hier vergessen. Ich fand den Vergleich mit der Klammer hier überhaupt nicht angebracht.

 
Alexey Navoykov:

Die Basis der Grundlagen einer zuverlässigen OOP.

Die Basis in der Eindeutigkeit.

 
Ilya Malev:

Ich sehe den Sinn von Referenzcode nicht (obwohl ich auch keine Standardbibliotheken verwende). Wenn das Einfügen eines Objekts in ein Array die Erstellung einer Kopie des Objekts beinhaltet, muss die Zuweisungsmethode oder der Kopierkonstruktor explizit in dieser Klasse deklariert und beschrieben werden, da sonst keine Wrapper helfen. Wenn Sie nur einen Verweis auf ein Objekt in ein Array stellen müssen, brauchen Sie überhaupt keine Wrapper (warum?).

Wozu brauchen Sie eine solche Anordnung? Da es fast analog zu einem Plusvektor ist, sollte es wie vector<int>, vector<class_name>, vector<class_name*> funktionieren. Wenn Sie es ohne Umhüllung mittels µl umsetzen können, ist das gut für Sie (ich glaube nicht, dass Sie das können). Sie haben keine Möglichkeit, ein Array zu durchlaufen und Destruktoren aufzurufen ( _data[i].~Destr() ), keine partielle Spezialisierung und keine SFINAE-Tricks. Dieses Wrapping macht das Array geeignet für Zeiger auf Objekte im Heap, ohne die Möglichkeit zu verletzen, z.B. mit vector<int> zu arbeiten.

vector<unique_ptr<my_class>> v1;

vector<my_class> v2;

vector<int> v3;

ZS: was zu sagen, vector<class_name*> wird nicht funktionieren, wie erwartet, auch in Plus (destructor Aufruf am Ende des Vektors Leben) es auch brauchen Wrapping.
 
pavlick_:

ZS: was zu sagen, vector<class_name*> wird nicht funktionieren, wie erwartet, auch in Plus (destructor Aufruf am Ende des Vektors Leben) es braucht Wrapping zu.

Wird das funktionieren? )

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.S. In Analogie dazu kann eine Funktion anstelle von void alles zurückgeben, und es wird kein SFINAE benötigt.

 
Ja, das ist in Ordnung. Aber wir brauchen immer noch einen Wrapper: Wir brauchen ein universelles Array, so dass es manchmal Zeiger hat, die gelöscht werden müssen, und manchmal nicht (nun, nur ein Satz von Zeigern - das Ergebnis der Suche nach etwas in einem anderen Array).
 
pavlick_:

Positiv zu vermerken ist, dass das Löschen von void* UB ist.

Übrigens habe ich nicht einmal darüber nachgedacht, danke für den Tipp. Es stellt sich heraus, dass delete in diesem Fall ähnlich wie free() ist. Es sollte verboten sein, da delete für Objekte positioniert ist und es einfach Speicher unter Umgehung von Regeln freigibt.

Zwar werden auch hier Destruktoren aufgerufen, aber bei der Portierung von Code nach C++ kann es zu Problemen kommen.

 
pavlick_:
Ja, das wird reichen. Aber wir brauchen immer noch Wrapping: schließlich brauchen wir universelle Array, so dass manchmal hat es Zeiger, die tun müssen, löschen, und manchmal nicht (gut, nur ein Bündel von Zeigern - das Ergebnis der Suche etwas in einem anderen Array).

Nun, niemand verbietet es, eine zusätzliche Option bei der Erstellung eines Arrays zu übergeben - ob Elemente beim Löschen gelöscht werden sollen oder nicht, und diese Option standardmäßig ein- oder auszuschalten (je nach Belieben). Schließlich kann man nie wissen, ob man etwas löschen will oder nicht)).

P.S. Übrigens löst das Einwickeln eines Zeigers vor dem Einfügen in ein Array nicht die Frage, ob das Basisobjekt beim Löschen des Arrays gelöscht werden muss oder nicht).
 
fxsaber:

Die zusätzlichen Klammern haben den Einfluss der sprachlichen Prioritäten vollständig eliminiert. Alles wird völlig eindeutig. Damit ist es 100%ig sicher, dass nach dem nächsten Build nichts mehr kaputt geht.

In diesem Sinne möchte ich zusammenfassen:


A100
Entwickler
fxsaber
Klammern
nur dort, wo sie unverzichtbar sind
vielleicht sogar an Stellen, wo MQL4 vorher anders war
sie werden überall gebraucht
unnötige Warnhinweise
nicht notwendig
nur an Stellen, wo MQL4 vorher anders war
überall benötigt
Prioritäten
ist erforderlich
erforderlich
im Prinzip nicht notwendig (da Klammern sie ersetzen)

Sollte ich mich nicht korrekt ausgedrückt haben - bitte korrigieren Sie mich - so habe ich mein Konzept kurz und unmissverständlich formuliert, wo Warnungen über Klammern erforderlich sind

 
Ilya Malev:

Nun, niemand verbietet, eine zusätzliche Option bei der Erstellung eines Arrays zu übergeben - ob Elemente beim Löschen zu löschen oder nicht, und machen es ein oder aus standardmäßig (nach Ihren Wünschen). Denn es ist schwer zu erraten, ob man etwas löschen sollte oder nicht)).

Im Allgemeinen kann man das so machen.

P.S. Übrigens, nur weil man einen Zeiger umhüllt, bevor man ihn in ein Array einfügt, wird die Frage, ob man sein Basisobjekt löschen muss oder nicht, wenn man das Array löscht, nicht klarer))


Wenn Sie es nicht einpacken, löschen Sie es nicht, wenn Sie es einpacken, löschen Sie es, das ist glasklar.

ZS: aber wenn ich es täte, würde ich es so ähnlich wie möglich mit der Standard-Plus-Bibliothek machen (Namen, Verhalten, usw.), also habe ich keine Wahl. Warum sollte man eine weitere Spezifikation erstellen, wenn bereits alles geschrieben ist?