Fehler, Irrtümer, Fragen - Seite 2419

 
Alexey Navoykov:

Was halten Sie davon, der Sprache die Möglichkeit hinzuzufügen, ein Argument als r-Wert zu übergeben? Dies würde alle Probleme sofort lösen und die Schaffung universeller Container für jeden Typ ermöglichen.

Wie? ) Universelle Container brauchen Links und Pfeile, nicht dieses Zeug.

Und der Durchschnittsnutzer ist nicht derjenige, der den r-Wert berechnet.

 
Alexey Navoykov:

Was halten Sie davon, der Sprache die Möglichkeit hinzuzufügen, ein Argument als r-Wert zu übergeben? Dies würde alle Probleme sofort lösen und die Erstellung von universellen Containern für jeden Typ ermöglichen. Insbesondere würde die obige Methode für r-Wert überladen werden:

Genau so ist es in allen STL-Containern implementiert.

Und der zweite Pluspunkt: es wird erlauben, move Konstruktoren zu definieren. Nun ist dies auch sehr fehlt, insbesondere für die Implementierung von Smart Pointers unique_ptr und andere Klassen, entworfen, um Monopol speichern einige einzigartige Ressource innerhalb, dh üblichen Kopie Konstruktoren sind inakzeptabel für sie.

Welchen Sinn hat es dann, einen Parameter per Referenz zu übergeben?

 
Slava:

Welchen Sinn hat es dann, den Parameter per Referenz zu übergeben?

Sie stellen sehr seltsame Fragen. r-Wert-Verknüpfungen sind nur für bewegte Semantik, normale Verknüpfungen sind für alles andere.
 
Slava:

Welchen Sinn hat es dann, den Parameter per Referenz zu übergeben?

Ich verstehe auch nicht wirklich, von welcher Art von Referenz Sie sprechen. Ursprünglich sagten wir, dass l-Wert-Referenzen (verfügbar in MQL) nicht alle Bedürfnisse abdecken, was durch die Unmöglichkeit der Übergabe einer Konstante oder eines Ausdrucks an eine solche Funktion demonstriert wurde. Für diesen Zweck wird eine r-Wert-Referenz benötigt, die alle anderen Typen akzeptiert. Somit wird die Kombination von zwei überladenen Funktionen für r-Wert und l-Wert sicherstellen, dass alle Typen von Argumenten akzeptiert werden, unabhängig von ihrer Herkunft.

Was Sie sagten, dass eine Konstante nirgendwo gespeichert, sondern on the fly erstellt wird, bedeutet, dass sie als r-Wert und nicht als l-Wert übergeben werden sollte (im Gegensatz zu C++). Es macht im Prinzip keinen Unterschied, in welcher Form sie interpretiert wird, die Hauptsache ist, dass sie in einer Funktion akzeptiert werden kann.

 
Alexey Navoykov:

Was Sie sagten, dass die Konstante nirgendwo gespeichert ist, sondern on the fly erstellt wird, bedeutet, dass sie in Form eines r-Wertes und nicht eines l-Wertes übergeben werden muss (im Gegensatz zu C++). Es macht im Prinzip keinen Unterschied, in welcher Form sie interpretiert wird, solange man sie in der Funktion akzeptieren kann.

Die r-Wert-Referenz impliziert eigentlich ein Objekt, für das die Verschiebung durchgeführt wird, d.h. es muss noch ein temporäres Objekt erstellt werden.

 
TheXpert:

Nun, eigentlich setzt eine r-Wert-Referenz voraus, dass es ein Objekt gibt, für das die Verschiebung durchgeführt wird, d.h. es muss ohnehin ein temporäres Objekt erstellt werden.

Offensichtlich existiert das Objekt immer irgendwo. Ich habe geschrieben, dass dieses Objekt "on the fly", d.h. vorübergehend, erstellt wird.

Aber ich glaube, ich habe verstanden, worum Slava gebeten hat. Er meinte, warum wir ein temporäres Objekt als Referenz akzeptieren müssen, wenn wir es als Wert akzeptieren können.

Nun, der Punkt ist, dass es unmöglich ist, eine Funktion gleichzeitig für Referenz und Wert in einer Kopie zu überladen:

template<typename T>
 void f(T) { }
template<typename T>
 void f(T const&) { }
 
class A { };

void OnStart()
{
  A a;
  f(a);
  const int b=0;
  f(b);  // 'f' - ambiguous call to overloaded function with the same parameters
}

Dies macht es problematisch, universelle Lösungen zu schreiben. Wenn wir den Wert durch den r-Wert ersetzen, erhalten wir eine funktionierende Variante:

template<typename T>
 void f(T &&) { }
template<typename T>
 void f(T const&) { }
 
Alexey Navoykov:

Er meinte, warum ein temporäres Objekt als Referenz nehmen, wenn man es als Wert nehmen kann.

denn

void f(int) {}
void f(const int&) {}

void OnStart()
{
   const int x = 0;
   f(x); // 'f' - ambiguous call to overloaded function with the same parameters
}

und weil es in der Regel bequemer ist, etwas per Referenz zu übergeben als per Wert.

Und wenn die Methode eine Vorlage ist (womit alles begann), dann erlaubt das derzeitige Verhalten einfach nicht, dass man richtig schreibt.

 
TheXpert:

Und wenn die Methode auf Vorlagen basiert (womit alles begann), dann ist es mit dem derzeitigen Verhalten einfach nicht möglich, richtig zu schreiben.

Ja, ich habe mein Beispiel durch eine Vorlage ersetzt, um es klarer zu machen, denn die per Referenz übergebenen Ints sehen wirklich nicht sehr überzeugend aus)
 
Alexey Navoykov:

Und wenn wir den Wert durch den r-Wert ersetzen, erhalten wir eine funktionierende Variante:

nicht wirklich )

Die Semantik des Verschiebens impliziert, dass dem zu verschiebenden Objekt mitgeteilt wird, dass es seine Interna nicht entfernen muss. Wenn das Objekt konstant ist, bräuchte man ein veränderbares Klassenmitglied, was mql nicht unterstützt

 
TheXpert:

nicht wirklich )

move semantics bedeutet, dem zu verschiebenden Objekt mitzuteilen, dass es seine Interna nicht entfernen muss. Wenn das Objekt eine Konstante ist, benötigen Sie ein veränderbares Klassenmitglied, mql unterstützt dies nicht

Ja, Sie haben Recht, const für r-Wert darf nicht gesetzt werden (es kompiliert nicht auf diese Weise in Pluszeichen). Ich werde es jetzt korrigieren)