Lassen Sie uns sagen, dass ich eine Klasse:Nicht Freund einzeiligen operator + Überlastung basierend auf Operator + =
class A
{
//...
};
Mit gut operator +=
definiert:
A& operator +=(const A&) {return *this;} //class without members
Lassen Sie uns also auch versuchen, zu überlasten operator+
(als Nicht-Freund). Ich will nicht, Klassennamen verwenden Konstruktor von temporären Objekt aufzurufen (ein bisschen wollen, dass diese generischen Code machen):
A operator +(const A& other) const
{
return auto(*this)(*this) += other; //error: invalid use of auto
// /\/\/\/\/\ /\
// type of *this ||
// constructor call
}
auto
hier nicht gut. Lass es uns versuchen decltype
.
A operator +(const A& other) const
{
return decltype(*this)(*this) += other; //error: 'A& A::operator+=(const A&)' discards
// /\/\/\/\/\/\/\ /\ qualifiers [-fpermissive] return
// type of *this || decltype(*this)(*this) += other;
// constructor call ^
}
Diese verwalten die Art von *this
zu bekommen, aber operator+
ist const deklariert, so bekamen wir const A
abgeleitet (das ist, was ich dachte). Also lass uns weitergehen:
A operator +(const A& other) const
{
return typename std::remove_const<decltype(*this)>::type(*this) += amount;
//same error as previous
}
Jetzt wurde ich verrückt. Selbst wenn ich die Konstanz entfernt habe, verwirft es immer noch Qualifier. Nun, vielleicht ist das nur, weil ich nur CASTING gemacht habe. So dumm. Um einen Konstruktor aufzurufen, müsste ich Code erzeugen, der (neben dem Typ) einen :: Constructor hat (also habe ich sogar versucht, einen Alias für Konstruktor zu erstellen, aber an dieser Stelle war ich so hart ausgefallen). Mein gebrochenes Gehirn gab, doch Rest meines Bewußtseins gab mir eine Lösung (die schriftlich generisch ist, so das ist gut):
// outside of class
template<class A>
inline A&& make_rvalue(A copy)
{
return std::move(copy);
}
// inside of class
A operator +(const A& other) const
{
return make_rvalue(*this) += other; // such generic code
}
Das ist, was ich mit beendet. Aber gibt es einen Trick, der keinen anderen Funktionsanruf beinhaltet?
EDIT: Ich weiß, klassische Methoden, dies zu tun, aber was ich suche ist unten beschrieben:
- Betreiber reduziert wird, um
{return /*...*/;}
- keine Namen von Klassenmethoden oder globale Funktionen beinhalten
- berücksichtigt Überladungen mit anderen Typen - es kann keine Argument (en) nach Wert nehmen, da
class A != class B
, Argumentint
überconst int&
hilft nicht viel mitMatrix
Klasse (aber Proxy-Operator, der Zieloperator mit ausgetauscht ar aufgerufen gumente ist OK) - nimmt (möglich) Reihenfolge der Operation zu berücksichtigen (
[email protected] != [email protected]
), wobei beide sollten gleiche return-Anweisung - return-Anweisung exacly für gegebene
[email protected]
gleich sein sollte, istoperator +=
jede Klasse, die überlastet haben sollte
Warum nicht einfach das Argument nach Wert anstelle von const ref nehmen? – Useless
Keine Ahnung, wovon du sprichst. –
Dieser 'Operator +' ist ** nicht ** generisch; Es wird in Objekten vom Typ "A" gerendert. Es gibt keinen Grund, den Typ A zu meiden, da Sie genau wissen, was es ist. Und selbst im generischen Code kennen Sie den Typ, mit dem Sie es zu tun haben. All diese Umschreibung ist sinnlos. –