Warum lässt C ++ 11 " delete
d" -Funktionen an der Überlastungsauflösung teilnehmen ?
Warum ist das nützlich? Oder mit anderen Worten, warum werden sie versteckt, anstatt vollständig gelöscht zu werden?
87
Warum lässt C ++ 11 " delete
d" -Funktionen an der Überlastungsauflösung teilnehmen ?
Warum ist das nützlich? Oder mit anderen Worten, warum werden sie versteckt, anstatt vollständig gelöscht zu werden?
Antworten:
Die Hälfte des Zwecks der
= delete
Syntax besteht darin, zu verhindern, dass Personen bestimmte Funktionen mit bestimmten Parametern aufrufen. Dies dient hauptsächlich dazu, implizite Konvertierungen in bestimmten Szenarien zu verhindern. Um eine bestimmte Überlastung zu verbieten, muss sie an der Überlastungsauflösung teilnehmen.Die Antwort, die Sie zitieren, gibt Ihnen ein perfektes Beispiel:
Wenn
delete
die Funktion vollständig entfernt würde, würde die= delete
Syntax dieser entsprechen:Sie könnten dies tun:
Dies ist legal C ++. Der Compiler betrachtet alle Konstruktoren. Keiner von ihnen nimmt direkt einen ganzzahligen Typ an. Aber einer von ihnen kann es nach einer impliziten Konvertierung nehmen. Also wird es das nennen.
Dies ist kein legales C ++. Der Compiler betrachtet alle Konstruktoren, einschließlich der
delete
d- Konstruktoren . Es wird eine genaue Übereinstimmung über angezeigtstd::intmax_t
(die genau mit jedem ganzzahligen Literal übereinstimmt). Der Compiler wählt es also aus und gibt sofort einen Fehler aus, da er einedelete
d-Funktion ausgewählt hat.= delete
bedeutet "Ich verbiete das", nicht nur "Das existiert nicht". Es ist eine viel stärkere Aussage.Das liegt daran, dass wir keine spezielle Grammatik benötigen, um zu sagen, dass dies nicht existiert. Wir erhalten dies implizit, indem wir das betreffende "dies" einfach nicht deklarieren. "Ich verbiete das" stellt ein Konstrukt dar, das ohne spezielle Grammatik nicht erreicht werden kann. Wir bekommen also eine spezielle Grammatik, um zu sagen "Ich verbiete das" und nicht die andere Sache.
Die einzige Funktionalität, die Sie durch eine explizite Grammatik "Dies existiert nicht" erhalten würden, besteht darin, zu verhindern, dass jemand sie später für existent erklärt. Und das ist einfach nicht nützlich genug, um eine eigene Grammatik zu benötigen.
Der Kopierkonstruktor ist eine spezielle Elementfunktion. Jede Klasse hat immer einen Kopierkonstruktor. So wie sie immer einen Kopierzuweisungsoperator, einen Verschiebungskonstruktor usw. haben.
Diese Funktionen existieren; Die Frage ist nur, ob es legal ist, sie anzurufen. Wenn Sie versuchen würden zu sagen, dass dies
= delete
bedeutet, dass sie nicht existieren, müsste die Spezifikation erklären, was es bedeutet, dass eine Funktion nicht existiert. Dies ist kein Konzept, das in der Spezifikation behandelt wird.Wenn Sie versuchen, eine Funktion aufzurufen, die noch nicht deklariert / definiert wurde, tritt ein Fehler beim Compiler auf. Es tritt jedoch ein Fehler aufgrund eines undefinierten Bezeichners auf , nicht aufgrund eines Fehlers "Funktion existiert nicht" (selbst wenn Ihr Compiler dies so meldet). Verschiedene Konstruktoren werden alle durch Überlastungsauflösung aufgerufen, so dass ihre "Existenz" in dieser Hinsicht behandelt wird.
In jedem Fall gibt es entweder eine über den Bezeichner deklarierte Funktion oder einen Konstruktor / Destruktor (ebenfalls über den Bezeichner deklariert, nur einen Typbezeichner). Das Überladen von Operatoren verbirgt die Kennung hinter syntaktischem Zucker, ist aber immer noch vorhanden.
Die C ++ - Spezifikation kann das Konzept einer "nicht existierenden Funktion" nicht verarbeiten. Es kann eine Überlastungsfehlanpassung behandeln. Es kann eine Überlastungsmehrdeutigkeit behandeln. Aber es weiß nicht, was nicht da ist. So
= delete
wird in Bezug auf die weitaus nützlicher definiert „Versuch , dies zu nennen scheitern“ , anstatt die weniger nützlich „so tun , als ich nie diese Zeile geschrieben hat .“Lesen Sie den ersten Teil noch einmal durch. Sie können dies nicht mit "Funktion existiert nicht" tun . Dies ist ein weiterer Grund, warum es so definiert wird: Einer der Hauptanwendungsfälle der
= delete
Syntax besteht darin, den Benutzer zu zwingen, bestimmte Parametertypen zu verwenden, explizit umzuwandeln usw. Grundsätzlich implizite Typkonvertierungen vereiteln.Ihr Vorschlag würde das nicht tun.
quelle
= delete
, dass "dieses Mitglied existiert nicht" bedeutet, was bedeuten würde, dass es nicht an der Überlastungsauflösung teilnehmen könnte.= delete
"dieses Mitglied existiert nicht" gemeint ist, kann das erste Beispiel, das ich gepostet habe, nicht verhindern, dass Leute Ganzzahlen anonlydouble
den Konstruktor übergeben , da dieonlydouble
gelöschte Überladung nicht existieren würde . Es würde nicht an der Überlastungsauflösung teilnehmen und Sie daher nicht daran hindern, Ganzzahlen zu übergeben. Welches ist die Hälfte des Punktes der= delete
Syntax: um sagen zu können: "Sie können X nicht implizit an diese Funktion übergeben."=delete
überhaupt? Schließlich können wir "nicht kopierbar" sagen, indem wir genau dasselbe tun: den Kopierkonstruktor / die Zuweisung als privat deklarieren. Beachten Sie auch, dass das Deklarieren von etwas Privatem es nicht unanrufbar macht. Code innerhalb der Klasse kann ihn weiterhin aufrufen. Es ist also nicht dasselbe wie= delete
. Nein, die= delete
Syntax ermöglicht es uns, etwas, das zuvor sehr unpraktisch und unergründlich war, viel offensichtlicher und vernünftiger zu machen.Der C ++ Working Draft 2012-11-02 liefert keine Begründung für diese Regel, nur einige Beispiele
quelle