Sind freie Betreiber->* überlastungen böse?
Ich war durchlesen Abschnitt 13.5 nach Widerlegung der Vorstellung, die built-in-Operatoren nicht an der überlast Auflösung, und festgestellt, dass es kein Abschnitt auf operator->*
. Es ist nur ein generischer binärer operator.
Seine Brüder, operator->
, operator*
, und operator[]
notwendig, um nicht-statische member-Funktionen. Dies schließt die definition eines freie Funktion überladen, um einen operator Häufig verwendet, um eine Referenz von einem Objekt. Aber die ungewöhnlich operator->*
übrig ist.
Insbesondere operator[]
hat viele Gemeinsamkeiten. Es ist binären (Sie verpasste eine goldene Gelegenheit, um es n-ary), und es übernimmt eine Art container auf der linken und eine Art von locator auf der rechten Seite. Seinen besonderen Regeln Abschnitt 13.5.5, nicht scheinen, um eine tatsächliche Wirkung, außer zu ächten Kostenlose Funktionen. (Und diese Einschränkung schließt auch Unterstützung für commutativity!)
So, zum Beispiel, das ist vollkommen legal:
#include <utility>
#include <iostream>
using namespace std;
template< class T >
T &
operator->*( pair<T,T> &l, bool r )
{ return r? l.second : l.first; }
template< class T >
T & operator->*( bool l, pair<T,T> &r ) { return r->*l; }
int main() {
pair<int, int> y( 5, 6 );
y->*(0) = 7;
y->*0->*y = 8; //evaluates to 7->*y = y.second
cerr << y.first << " " << y.second << endl;
}
Es ist leicht zu finden verwendet, sondern alternative syntax, neigt nicht so schlimm zu sein. Zum Beispiel, skaliert Indizes für vector
:
v->*matrix_width[2][5] = x; //->* not hopelessly out of place
my_indexer<2> m( v, dim ); //my_indexer being the type of (v->*width)
m[2][5] = x; //it is probably more practical to slice just once
Hab den standards committee vergessen, um dies zu verhindern, wurde es als zu hässlich, zu stören, oder gibt es real-world use cases?
- Ein Datenpunkt: Coneau (comeaucomputing.com/tryitout) lehnt Ihren code auch nachdem ich den entfernt
<type_traits>
und der erste operator:error: no operator "->*" matches these operands
- Comeau war der erste Ort, den ich ging, um zu versuchen und zu sehen. Ich habe noch diese tab zu öffnen... der einzige code, den ich vor dem Wechsel zu GCC 4.5 wurde "struct x { int y; }; int & - operator->*( x &l, int r ) { return l.y; } void f() { x q; int &i = q->*3; }". — und es gibt Erfolge für das wichtigste Beispiel minus alles abhängig von der ersten type_traits abhängigen überlast.
- Ich weiß nicht, warum Betreiber->* können überladen werden, aber es sieht sicher hella hässlich! Ich würde bleiben Weg von es aus dem gleichen Grund wie überlastung durch Komma scheint es nicht so intuitiv zu C++.
Du musst angemeldet sein, um einen Kommentar abzugeben.
Das beste Beispiel, das ich mir bewusst bin, ist Boost.Phoenix, die überlastungen dieser operator zu implementieren faul member-Zugang.
Für diejenigen, die nicht mit Phoenix, es ist eine höchst raffinierte Bibliothek für das erstellen von Schauspieler (oder function-Objekte), die Aussehen wie normale Ausdrücke:
Erreicht der oben durch überlastung
operator%
undoperator==
. angewendet werden, um die Schauspielerarg1
diese Operatoren Rückkehr ein anderer Schauspieler. Die Palette der Ausdrücke, die gebaut werden können auf diese Weise extrem:Nachdem Sie wurden mit Phoenix für eine kurze Zeit (nicht, dass Sie jemals wieder gehen) wird man versuchen, so etwas wie dieses:
Was fehlschlägt, weil der Kurs von Phoenix Akteure, die nicht Mitglied
ValidStateBit
. Phoenix bekommt um diese durch überlastungoperator->*
:operator->*
's Argumente sind:MyObj *
Gibt es einen Schauspieler, der die Auswertung der LHS und sucht das angegebene Element in ihm. (NB: hat Sie wirklich, wirklich wollen, stellen Sie sicher, dass
arg1
zurückMyObj *
- Sie haben nicht gesehen, eine riesige Vorlage Fehler, bis Sie etwas falsch in Phoenix. Dieses kleine Programm generiert 76,738 Zeichen von Schmerzen (Boost 1.54, gcc 4.6):Ich Stimme mit Ihnen überein, dass es eine Inkohärenz, die auf dem standard, ist Es nicht erlaubt das überladen von
operator[]
mit nicht-member-Funktionen und ermöglicht es füroperator->*
. Aus meiner Sichtoperator[]
ist, um arrays alsoperator->*
ist structs/Klassen (a getter). Mitglieder eines Arrays ausgewählt sind, wird ein index verwendet. Die Mitglieder einer Struktur ausgewählt sind, mit Element-Pointer.Das Schlimmste ist, dass können wir versucht sein, zu verwenden
->*
stattoperator[]
um ein array-elementGibt es auch andere mögliche Inkohärenz. Wir können ein nicht-member-Funktion, um eine überlastung
operator+=
und alle operator der form@=
) und wir können es nicht füroperator=
.Ich weiß wirklich nicht, was ist die Begründung, um die folgenden rechtlichen
und verbietet
Leider keine Antwort auf deine Frage, aber das hinzufügen noch weitere Verwirrung zu Stiften.
operator ->
undoperator @=
müssen, werden member-Funktionen. Die kostenlosen Funktionen können unterstützt werden durch den compiler, aber das ist sicherlich flippig.operator=
soll nicht besonders sein.operator =
ist in D&E.operator =
ist das Besondere in dem Sinne, dass der compiler immer, wenn Sie deklarieren Sie nicht Ihre eigenen in der Klasse definition. Wenn nicht-Mitgliedoperator =
erlaubt waren, könnten Sie es in der Mitte der übersetzungseinheit. In diesem Fall wird der code, der sich oben, die definition müssten die compiler-sofern Mitgliedoperator =
und den code unter, die definition müssten die explizit definierten nicht-Mitgliedoperator =
- inkonsistent. Um zu vermeiden, die Inkonsequenz, standaloneoperator =
wurde verboten.operator =
besonderes ist.bool
nicht gebaut-in?? Ich denke die Kompatibilität ist wichtig... Warum wird in der Zusätzlichen Anmerkung von Oktober 2000 erscheinen nach dem vorgeschlagenen Beschluss vom April 2001? Und die resolution verabschiedet, in der FCD-aber 13.5.3 nicht geändert, so es ist ziemlich viel unklar, wie immer...int &operator+=( int &lhs, MyExpr<…> &rhs )
ist eine legitime Nutzung, die sich ziemlich eng an den ARM-problem. Sollte ich gedacht habe, der früher.operator=
Googeln Sie ein bisschen herum, fand ich mehrere Instanzen von Leuten gefragt, ob
operator->*
überhaupt benutzt wird, als tatsächliche Vorschläge.Ein paar Orte vorschlagen
T &A::operator->*( T B::* )
. Nicht sicher, ob dies spiegelt designer ' s Absicht oder ein misimpression, dassT &A::operator->*( T A::* )
ist ein builtin. Nicht wirklich in Bezug auf meine Frage, aber gibt eine Vorstellung von der Tiefe fand ich in der online-Diskussion & Literatur.Gab es eine Erwähnung der "D&E 11.5.4", die ich vermute, ist das Design und Evolution von C++. Vielleicht enthält einen entsprechenden Hinweis. Ansonsten, ich bin nur gonna schließen, es ist ein bisschen nutzlos, Hässlichkeit, dass übersehen wurde, die Standardisierung und die meisten anderen auch.
Bearbeiten Siehe unten für eine paste, die D&E Angebot.
Diese quantitativ
->*
ist die engste Bindung operator können überladen werden, indem eine Kostenlose Funktion. Alle postfix-Ausdruck und unäre Operatoren überlastungen erfordern eine nichtstatische member-Funktion Unterschriften. Nächste Priorität nach unären Operatoren im C-Stil-casts, die gesagt werden könnte, zu entsprechen Konvertierungsfunktionen (operator type()
), die man auch nicht Kostenlose Funktionen. Dann kommt->*
, dann die Multiplikation.->*
hätte wie[]
oder wie%
Sie gegangen sein könnte oder so, und Sie entschied sich für den Weg der EEEEEEVIL.operator->
erlaubt ist und die Begründung (oder 2) für das zulassen vonoperator+=
aber verbietenoperator=
ist, war in den Kommentaren. Und ich war nicht wirklich auf der Suche nach (dis -) Abkommen, die Frage war Hat der Normen-Ausschuss vergessen, um dies zu verhindern, wurde es als zu hässlich, zu stören, oder gibt es real-world use cases?, das ist eine Frage der Suche nach ein paar Referenzen oder Belege, die für eine der Schlussfolgerungen.operator ->*
gemacht wurde overloadable vor allem, weil es gab keinen Grund, nicht zu (wegen der Orthogonalität, wenn Sie müssen). Es stellt sich heraus, nützlich zu sein für den Ausdruck von binding-Operationen, die irgendwie Semantik haben, dass die parallelen die der built-in der Bedeutung für->*
. Keine besonderen Regeln erforderlich sind;->*
verhält sich genau wie jede andere binäre Betreiber.operator .*
war nicht unter den Betreibern könnte ein Programmierer überlastung aus dem gleichen Grundoperator .
war das nicht."operator=
(es war legal). Es scheint, dass in diesem Punkt, stellte er eine überlastung auf[]
,()
, und->
und Sie benötigt, um Mitglieder: "es schien eine Harmlose Einschränkung, dass eliminiert die Möglichkeit, einige obskure Fehler, da diese Operatoren immer abhängen, und in der Regel ändern Sie den Zustand Ihrer linken Operanden", aber dann: "Jedoch, es ist wahrscheinlich ein Fall von unnötiger nannyism." Es scheint, dassoperator->*
undoperator,
wurden später Hinzugefügt und entkam dieser.Standard (Working Draft 2010-02-16, § 5.5) sagt:
Möchten Sie vielleicht dieses Verhalten zu gut definiert. Zum Beispiel, ob es ein null-Zeiger ist und mit dieser situation umzugehen. ALSO ich quess es ist die richtige Entscheidung für einen standard zu ermöglichen ->* überlastung.
operator/
überlastung kann definieren Verhalten für seine zweite operand null ist, und rechtlich kann man das nutzen.