Kürzlich habe ich versucht, einen Konvertierungsoperator als Alternative zu operator []
zu verwenden.
Wie der folgende Code:
%Vor%Ich fand es funktioniert in G ++ aber nicht in MSVC v141 (2017).
MSVC meldet:
%Vor%Also ist das ein Fehler von MSVC oder etwas anderes? Und wie arbeitest du?
Dies ist ein MSVC-Fehler. Die Kandidaten sind nicht zweideutig. Die Umgehungslösung würde entweder darin bestehen, eine benannte Konvertierungsfunktion für ein Array bereitzustellen oder einfach ein benutzerdefiniertes operator[]
bereitzustellen.
Wenn wir Operatoren verwenden, haben wir [over.match .oper] :
Wenn einer der Operanden einen Typ hat, der eine Klasse oder eine Aufzählung ist, kann eine benutzerdefinierte Operatorfunktion deklariert werden, die diesen Operator implementiert, oder eine benutzerdefinierte Konvertierung kann erforderlich sein, um den Operanden in einen geeigneten Typ umzuwandeln ein eingebauter Operator.
In f[0]
, f
hat den Klassentyp. Daher berücksichtigen wir entweder die benutzerdefinierten Operatorfunktionen oder benutzerdefinierte Konvertierungen. Es gibt keine der ersten, aber zwei der letzteren. Beide sind brauchbare Kandidaten:
Also müssen wir eine Überladungsauflösung durchführen, um den besten Kandidaten auszuwählen. Der Unterschied zwischen den beiden ist der implizite Objektparameter. Gemäß [over.match.funcs] :
Damit diese Argument- und Parameterlisten innerhalb dieser heterogenen Menge vergleichbar sind, wird davon ausgegangen, dass eine Elementfunktion einen zusätzlichen Parameter hat, den impliziten Objektparameter, der das Objekt darstellt, für das die Elementfunktion aufgerufen wurde. Für die Zwecke der Überladungsauflösung verfügen sowohl statische als auch nicht statische Elementfunktionen über einen impliziten Objektparameter, Konstruktoren jedoch nicht. [...]
Für nicht statische Elementfunktionen ist der Typ des impliziten Objektparameters
- "lvalue reference to cv X" für Funktionen, die ohne Ref-Qualifier oder mit & amp; Ref-Qualifier
[...] wobei X die Klasse ist, deren Funktion ein Member ist und cv die cv-Qualifizierung für die Memberfunktionsdeklaration ist. [...] Für Konvertierungsfunktionen wird die Funktion als Mitglied der Klasse des implizierten Objektarguments betrachtet, um den Typ des impliziten Objektparameters zu definieren.
So verhält sich die Überladungsauflösung hier so, als hätten wir:
%Vor%An diesem Punkt sagen uns die ICS-Rankingregeln Folgendes:
Die Standardkonvertierungssequenz S1 ist eine bessere Konvertierungssequenz als die Standardkonvertierungssequenz S2, [...] wenn S1 und S2 Referenzbindungen sind und die Typen, auf die sich die Referenzen beziehen, vom selben Typ sind, außer für CV-Qualifikationsmerkmale auf oberster Ebene , und der Typ, auf den sich die durch S2 initialisierte Referenz bezieht, ist cv-qualifizierter als der Typ, auf den sich die durch S1 initialisierte Referenz bezieht.
Die Referenzbindung in #1
ist weniger cv-qualifiziert als die Referenzbindung in #2
, also ist es eine bessere Übereinstimmung. Da es eine bessere Übereinstimmung ist, haben wir am Ende eine einzigartige, am besten praktikable Funktion, und der Ruf ist wohlgeformt.
Außerdem sollte es hier keine Rolle spielen, wenn die Konvertierungsoperatoren Zeiger oder Referenzen auf Arrays zurückgeben. Die zugrunde liegenden Regeln sind die gleichen, aber MSVC ermöglicht die vorherige . Und MSVC ermöglicht dies auch:
%Vor%Tags und Links c++ visual-c++ language-lawyer