2016-08-01 15 views
1

Ich habe Code, wodurch ich eine Struktur für eine std::set von Objekten des Typs A abfragen kann, die alle einige Kriterien erfüllen. Ich möchte sehr oft, dass meine Abfragekriterien so sind, dass der Code eine Menge zurückgibt, die nur ein Objekt enthält. Und in diesen Fällen möchte ich, dass mein Code fehlschlägt, wenn die Abfrage nicht nur ein Ergebnis erzeugt hat. So würde Ich mag eine Funktion machenWas ist die definierende Qualität des Indirektionsoperators?

A& deref_or_throw(std::set<A> s) 
{ if (s.size() != 1) throw ...; return *s.begin(); } 

, die wirft, wenn der Satz mehr als ein (oder keine) Element enthält, und dereferenziert das erste Element anders.

Der Kürze halber, dachte ich den Indirektionsoperator zu überlasten, die nicht für std::set definiert:

A& operator*(std::set<A>& s) {return deref_or_throw(s);} 

Ist dies eine schlechte Idee? Es passt mit dem Konzept des Indirektionsoperators, dass es eine Dereferenzierung durchführt. Aber ich konnte keine strenge Definition dafür finden, was der Indirektionsoperator gemäß den Standards tun sollte, um sicherzustellen, ob ich seinen Standardgebrauch pervertiere (zu weit).

+5

Für mich ergibt es keinen Sinn. '*' bedeutet, gib mir das auf das Objekt hingewiesen. Ich hasse es, Operatoren zu verwenden, die etwas anderes machen als das, was sie für einen Standardtyp tun würden. – NathanOliver

+0

@NathanOliver: also sollten Sie nicht operator '<<' zum Einfügen von Objekten in Streams verwenden, da dies ursprünglich der bitweise Linksverschiebungsoperator ist ... – shrike

+2

@shrike Was meinen Sie ursprünglich? Als C++ in 98 standardisiert wurde, war es sowohl der Sift- als auch der Stream-Operator. Sollten sie einen neuen Betreiber gemacht haben, IDK. Ist es zu spät, um es jetzt zu ändern, ja – NathanOliver

Antwort

2

Überlasten Sie auf diese Weise nicht operator*. Die Kürze einer Person ist die Verschleierung einer anderen Person.

In diesem Fall gibt es keinen Präzedenzfall für operator* auf jedem Standard-Container Betrieb so in der Zukunft, wenn jemand an der Code sieht sie keine Ahnung haben, was es tut, ohne die die Umsetzung Ihrer operator* zu finden. Nimm stattdessen die zusätzlichen 10 Sekunden in Anspruch, um den Namen deines Funktionsaufrufs zu kopieren und zu speichern, und speichere deine zukünftigen Betreuer, die wissen, wie viel Zeit es dauert, die Überlastung des Bedieners in einem Jahr zu finden.

Ich würde vorschlagen, etwas wie *ensure_single_element(your_set).begin() oder etwas, wo es ganz klar ist, was los ist.

+0

Das beantwortet die Frage nicht ... – ciamej

+1

Die OP Frage, die ich sehe, ist "ist das eine schlechte Idee?".Zu mir sagt diese Antwort, ja ist es und schlägt eine geeignete Alternative vor, und warum (d. H. Lesbarkeit). –

+0

Ich setze einen "nein, tu das nicht" führenden Satz und lasse die bestehende Argumentation bestehen. –