Kann ein überladener Operator in eine Nicht-Member-Funktion umgewandelt werden, um Code zu brechen?

9

Betrachten Sie eine Legacy-Klassenvorlage mit überladenen Additionsoperatoren += und +

%Vor%

Bei der Code-Überprüfung wird beobachtet, dass + in += implementiert werden kann. Warum also nicht ein Nicht-Member (und garantiert Symmetrie für linke und rechte Argumente)? ​​

%Vor%

Es sieht sicher genug aus, weil alle gültigen Ausdrücke, die + und += verwenden, ihre ursprüngliche semantische Bedeutung behalten.

Frage : Kann das Refactoring von operator+ von einer Member-Funktion in eine Nicht-Member-Funktion einen Code unterbrechen?

Definition der Bruchstelle (schlechteste bis beste)

  • neuer Code wird kompiliert, der nicht im alten Szenario
  • kompiliert wurde
  • alter Code wird nicht kompiliert, der unter dem alten Szenario kompiliert wurde
  • Neuer Code ruft automatisch ein anderes operator+ auf (von der Basisklasse oder dem zugehörigen Namespace, der über ADL gezogen wurde)
TemplateRex 28.09.2014, 20:10
quelle

1 Antwort

3

Zusammenfassung

Die Antwort ist, ja, es wird immer Bruch geben. Der wesentliche Bestandteil ist, dass die Argumentableitung von Funktionsvorlagen keine impliziten Konvertierungen berücksichtigt. Wir betrachten drei Szenarien, die die drei syntaktischen Formen abdecken, die ein überladener Operator annehmen kann.

Hier verwenden wir einen impliziten Konstruktor innerhalb von X<T> selbst. Aber selbst wenn wir diesen Konstruktor explicit hätten, könnten Benutzer dem Namensraum X<T> eine Klasse C<T> hinzufügen, die eine implizite Konvertierung der Form operator X<T>() const enthält. Die folgenden Szenarien würden in diesem Fall weiterhin gelten.

Eine Friend-Funktion, die kein Mitglied ist, bricht am wenigsten in dem Sinne, dass sie implizite Konvertierungen von lhs-Argumenten erlaubt, die nicht für die Member-Funktion einer Klassenvorlage kompiliert werden. Die Nicht-Member-Funktionsvorlage bricht die implizite Konvertierung für rhs-Argumente.

Memberfunktion der Klassenvorlage

%Vor%

Dieser Code erlaubt einen Ausdruck wie

%Vor%

Nicht-Mitglied-Freund-Funktion

%Vor%

Da die Funktion friend keine Vorlage ist, findet keine Argumentableitung statt, und sowohl das Argument lhs als auch rhs betrachten implizite Konvertierungen

%Vor%

Vorlage für Nichtmitgliedsfunktion

%Vor%

In diesem Fall werden die Argumente lhs und rhs einer Argumentableitung unterzogen und berücksichtigen keine impliziten Konvertierungen:

%Vor%     
TemplateRex 29.09.2014, 18:09
quelle