Der Ausdruck new int;
wie in int * x = new int;
ist ein neuer Ausdruck . Der Begriff "neuer Operator" scheint synonym mit "neuer Ausdruck" verwendet zu werden, zum Beispiel in dieser Frage: Unterschied zwischen "neuer Operator" und "neuer Operator"?
Ist es richtig zu sagen, dass das Schlüsselwort, new
wie es in einem neuen Ausdruck verwendet wird, ein Operator ist? Warum oder warum nicht?
Wenn nicht, gibt es eine andere Rechtfertigung dafür, einen neuen Ausdruck "neuer Operator" zu nennen?
Ich habe Probleme, eine maßgebliche Definition für das zu finden, was einen Operator ausmacht.
Ich verstehe bereits die Unterscheidung zwischen dem Operator new, der einem Objekt Speicher zuweist, und dem "neuen Ausdruck", der möglicherweise einen aufruft operator new
.
quelle
new
ist wiesizeof
hier. Und ich denke, die Mehrheit der C ++ - Community denkt ansizeof
einen Operator. Der Standard bezieht sich bei dersizeof
Beschreibung seiner Auswirkungen sogar auf den " Operator".sizeof
, ich würde sagen, das wäre der Operator eines Ausdruckssizeof(<type>)
. Und+
ist ein Operator für einen unären Ausdruck<type> <op> <type>
. Das ist zumindest meine Erkenntnis zum Mitnehmen. Sie können mich gerne korrigieren.new
es sich um einen Operator handelt oder nicht, gibt es einen Unterschied zwischen einem Ausdruck und einem Operator. ZBnew int
ist ein Ausdruck, wie er zu etwas auswertet. Wennnew
es sich um einen Operator handelt, ist nur der "neue" Teilnew int
der Operator (dh es ist eine eigene Sache). Konzeptionell ist ein Operator etwas, das auf etwas anderes einwirkt.Antworten:
new
innew int
gilt nicht als Betreiber. Es wird auch nicht als kein Betreiber angesehen.Der C ++ - Standard ist wirklich vage und sogar inkonsistent, was einen "Operator" ausmacht. Beim Auflisten von Operatoren (wie beim Lexieren und Vorverarbeiten definiert) werden diese zusammen mit "Interpunktionszeichen" (z. B.
(
) aufgelistet, es werden jedoch nie wirklich Regeln für Interpunktionszeichen im Allgemeinen angegeben. Es wirdnew
sowohl als Schlüsselwort als auch als Operator aufgeführt. Es wirdsizeof
in der Gruppe der Schlüsselwörter aufgeführt, jedoch NICHT in der Gruppe der Operatoren, wird jedoch später als Operator bezeichnet.Das Wichtigste dabei ist, dass sich das C ++ - Standardkomitee nicht allzu sehr mit der Trennung der lexikalischen Welt in "Operatoren" und "Nichtoperatoren" befasst. Dies liegt daran, dass dies nicht wirklich erforderlich ist. Es gibt keine grammatikalischen Regeln, die für alle Operatoren oder alle Nichtoperatoren gelten. Wichtige Sätze, wie der Satz überladbarer Operatoren, werden separat angegeben. Grammatikregeln für Dinge wie binäre arithmetische Ausdrücke werden einzeln angegeben.
Grundsätzlich ist "Operator" keine Kategorie, die für die C ++ - Sprache formal von Bedeutung ist. Daher wird jede kategoriale Antwort darauf basieren, wie sie sich "anfühlt". Sie können es als Operator bezeichnen, wenn Sie möchten, aber Sie können es auch als Schlüsselwort (oder Interpunktionszeichen!) Nennen, und der Sprachstandard wird Ihnen nicht widersprechen.
quelle
Nein. Das
new
in einem neuen Ausdruck ist ein Schlüsselwort, das einen neuen Ausdruck identifiziert .Ein neuer Ausdruck ruft ein
operator new
oderoperator new[]
auf, um Speicherplatz zu erhalten. Außerdem wird dieser Speicher initialisiert und die Zuordnung (mitoperator delete
oderoperator delete[]
) aufgehoben, wenn die Initialisierung ausgelöst wird.Es gibt eine klare Unterscheidung, die
operator new
nur alsüberladbare, vomBenutzer austauschbare Funktion bezeichnet wird, und ein neuer Ausdruck kann mehr als nur diese Funktion aufrufen.Referenz: 7.6.2.8/10
[expr.new]
Betrachten Sie als Gegenbeispiel, dass wir beide definieren
T operator+(T, T); void* T::operator new(std::size_t);
für einige Typ T dann Addition in jeder Form:
T a, b; T c = a + b; T d = T::operator +(a, b);
ist identisch. Die Infixnotation ist nur syntaktischer Zucker für den Operatoraufruf.
Die Zuordnung verhält sich jedoch ganz anders:
T *p = new T; // does much more than void *v = T::operator new(sizeof(T));
Daher ist es nicht sinnvoll, den syntaktischen Zucker mit dem neuen Ausdruck für einen Aufruf von aufzurufen
operator new
. Dasnew
Schlüsselwort wählt also nicht einfach die aufzurufende Funktion aus. Es kann nicht sein, oder es müsste dieoperator delete
Funktion erwähnen , die auch aufgerufen werden könnte.quelle
operator new
Ist ein überladbarer Betreiber" - oder?! Ich glaube nicht:operator +
ist kein überladbarer Operator -+
und Sie definieren Überladungen über eine aufgerufene Funktionoperator +
.new
Schlüsselworts adressiert, wie es in einem neuen Ausdruck erscheint.new
legt die Tatsache, dass der Operator überlastet ist, nahe, dass die Antwort ja sein sollte ,new
(selbst) ist ein Operator.Ich würde es nur als neuen Ausdruck bezeichnen , um Verwechslungen zu vermeiden, bei
void* operator new ( std::size_t count )
denen der neue Ausdruck nur als Teil des Prozesses zugewiesen wird (Zuordnungsspeicher, Startlebensdauer, aufrufender Konstruktor).Das Problem dabei
new
ist, dass es mehr als nur das Aufrufen desoperator new
. Welches ist ein bisschen verwirrend, weil fürx + y
die+
einzigen Anrufeoperator +
.quelle
Dies wird durch [expr.new] geregelt , das klar zwischen einem neuen Ausdruck und der Art und Weise unterscheidet, wie ein neuer Ausdruck durch Aufrufen einer Zuweisungsfunktion , die benannt wird , Speicherplatz erhält
operator new
. Insbesondere aus [expr.new] / 8 [ Schwerpunkt Mine]:Insbesondere das Beispiel von [expr.new] / 4 , wenn auch nicht normativ, beschreibt diese Funktion als Operatorfunktion; "[...] der
new
Betreiber" :quelle
Nein.
Nun, irgendwie ja, in dem Sinne , dass es Menschen gibt , die die Meinung
new
innew int
einem Operator sein. Diese Meinung steht jedoch (meistens) im Widerspruch zum Standard.Zum einen
[lex.operators/1]
werden die Operatoren in der Sprache. Lassen Sie sich nicht täuschen, dass dies auch nur "Vorverarbeitungsoperatoren" sind. Eine solche Unterscheidung besteht nicht im Sinne von lexikalischen Operatoren. Es wäre auch nicht sinnvoll, da Sie (zum Beispiel)++
kein Makro können.new
ist in der Tat ein Schlüsselwort (per[lex.key/1]
).Schauen wir uns als nächstes den neuen Ausdruck selbst an. Hier wird es etwas wolliger. Es gibt zum Beispiel den folgenden Wortlaut in
[expr.new/4]
:Ich halte dies für einen redaktionellen Fehler, da er im Widerspruch zu den oben angegebenen Definitionen steht und nirgendwo anders in diesem Abschnitt vorkommt.
Dann kommen wir zur Überlastung des Bedieners . In seiner grammatikalischen Erstellung für eine Operatordeklaration wird das Terminal, das Dinge (einschließlich
new
) auflistet, als Operator ([over.oper.general/1]
) bezeichnet. Ich glaube nicht, dass wir uns darüber Sorgen machen müssen. Die Namen von Terminals in der Grammatik sollten niemals Definitionen von Begriffen einführen. Schließlich haben Sie den Ausdruck, dass _ keine bitweise UND-Verknüpfung sein muss. es kann nur ein Gleichheitsausdruck sein :Es ist üblich, Grammatiken wie diese zu definieren, und dies bedeutet sicherlich nicht, dass jeder Gleichheitsausdruck irgendwie als Aufruf des bitweisen AND-Operators zu betrachten ist.
Schließlich haben einige behauptet, dass der folgende Wortlaut (auch im Abschnitt zum Überladen von Operatoren) ein Beweis dafür
new
ist, dass er jetzt irgendwie isoliert magisch ein Operator ist:Ich sage ihnen, dass nicht nur
new
nicht einmal aufgeführt ist, sondern dass der Begriff "Operator" eindeutig im weiteren Sinne von "Dinge, die überladen werden können" verwendet wird, obwohl ernew
an sich immer noch kein Operator ist . Es ist auch in einer nicht normativen Notiz, die Ihnen alles sagen sollte, was Sie wissen müssen.Und wie Sie selbst betonen, betrachten wir bereits
operator new
etwas anderes.quelle
sizeof
ein Operator ist. [expr.throw] ist in Bezug auf weniger explizit,throw
spricht aber immer noch von einem „Operanden“throw
, was impliziert, dassthrow
es sich um einen Operator handelt.Obwohl ich weiß, dass Sie nach einer semantischen Antwort suchen, würde ich meiner Meinung nach sagen, dass es sich um ein "Schlüsselwort" handelt (da es eindeutig reserviert ist), und ich gehe davon aus, dass wir beide wissen, dass es einfach das Konstrukt von C ++ für die Speicherzuweisung ist. Das heißt, wenn ich an die "Operatoren" von C ++ denke, denke ich eher an Funktionen mit einer festgelegten Eingabe / Ausgabe, die für bestimmte Typen überschrieben werden kann. new ist für alle Typen gleich (und verwirrender kann es überschrieben werden).
Ich bin mir nicht sicher, wie die offizielle Referenz ist, aber:
https://en.cppreference.com/w/cpp/language/new
Es scheint dann zu folgen, dass dies
new <type>
ein Ausdruck zum Zuweisen von Speicher ist, währendnew
der Operator für diesen Ausdruck ist.Mit der gleichen Logik:
sizeof
ist ein "Operator" für den Ausdrucksizeof(<type>)
(obwohlsizeof
es sich um einen Operator zur Kompilierungszeit handelt, der sich ein wenig von dem unterscheidet, was wir gewohnt sind)+
ist ein Operator für einen Ausdruck<type> <operator> <type>
throw
ist ein Operator für den Ausdruckthrow <throwaable>
quelle
[]()
auch ein Operator? Istfor
? Istthrow
?[]
und()
separate Betreiber bilden. Wiederfor
ist absolut ein Schlüsselwort, aber wo ich als Operator beschreiben würde, war der erste Teil der Möglichkeit, überschrieben zu werden. Technisch durch , dasssizeof
kein Betreiber, das gilt für C ++, dass es eher eine Vorverarbeitung Ausdruck ist. Undthrow
ist ein Operator eines Ausdrucksthrow <throwable>
[]()
in Kombination, wenn ich ein Lambda definiere. Ihre Antwort ist aber auch interessant, weil (in C ++) die Antwort vom Kontext abhängt: infoo()
,()
ist ein (überladbarer!) Operator; in(1 + 2)
es keinen Operator überhaupt ist (in einigen anderen Sprachen, insbesondere R, das ist anders). Auf jeden Fall reicht das überschreibbare Kriterium nicht aus. Es gibt viele Dinge in C ++ , die eindeutig Betreiber trotz nicht überladbaren sind (.
,::
,:?
, beidesizeof
s, etc).[]()
als Lambda ist es schwierig, es zu definieren (insbesondere, weil ich mit meinem C ++ nicht so auf dem neuesten Stand bin). Hier würde ich also immer noch sagen , dass sie[]
()
verschiedene Operatoren eines Lambda- Ausdrucks darstellen , aber ich bin mir nicht sicher, ob Sie argumentieren würden, dass sie nicht überschrieben werden können, oder ob die bloße Implementierung / Deklaration eines Lambdas das Überschreiben des grundlegenden Lambdas darstellt (wie z in Java). Sprachdesign wird dort zu einer Kunst über der Wissenschaft. Soweit( ... )
es ein Trennzeichen in den meisten langs ist, die ich verwendet habe, aber ich werde R ganz schnell genauer betrachten(a + b)
semantisch identisch mit dem Funktionsaufruf "(" (a + b)) oder "(" ("+" (a, b))), wobei "x" verwendet werden kann, um einen Namen zu erstellenx
syntaktisch eher einem Funktionsaufruf als einem speziellen entsprechen (z. B. einem Infix-Operator).