Ich war überrascht von der Tatsache, dass GCC nicht den Aufruf von foo()
im folgenden Programm nicht eindeutig betrachtet:
Der obige Funktionsaufruf kompiliert und gibt true
auf GCC 4.7.2 und GCC 4.8.0 (beta) zurück, während es nicht (wie ich erwarten würde) auf Clang 3.2 und kompiliert ICC 13.0.1.
Ist dies ein Fall von " no diagnostic required " oder handelt es sich um einen Fehler in GCC? Verweise auf den C ++ 11 Standard werden empfohlen.
>§7.3.3 / 3:
In einer using-Deklaration, die als Member-Deklaration verwendet wird, muss der Nested-Name-Specifier eine Basisklasse der Klasse definieren, die definiert wird. Wenn eine solche using-Deklaration einen Konstruktor benennt, muss der Nested-Name-Specifier eine direkte Basisklasse der Klasse definieren, die definiert wird. andernfalls wird die Gruppe der Deklarationen eingeführt, die durch die Suche nach Membernamen (10.2, 3.4.3.1) gefunden wurde.
¶14:
... [Anmerkung: Zwei using-Deklarationen können Funktionen mit demselben Namen und denselben Parametertypen einführen. Wenn die Funktionsüberladungsauflösung für einen Aufruf eines nicht qualifizierten Funktionsnamens die Funktionen auswählt, die durch solche using-Deklarationen eingeführt werden, ist der Funktionsaufruf schlecht gebildet.
¶16:
Zum Zweck der Überladungsauflösung werden die Funktionen, die durch eine using-Deklaration in eine Die abgeleitete Klasse wird so behandelt, als wären sie Mitglieder der abgeleiteten Klasse.
Die using
-Deklarationen sind also legal, aber die Funktionen sind Peers in der gleichen Überladungsmenge, wie Sie sagten, und das Programm ist schlecht gebildet.
Der Aufruf von foo(true)
in Ihrem Programm ist, wie Sie sagen, eindeutig mehrdeutig; außerdem ist es gemäß dem in § 10.2 vorgestellten Algorithmus mehrdeutig und sollte daher bei der Verwendung gekennzeichnet werden. (Die Angabe der using
-Deklaration würde falsch sein; 10.2 (1) gibt eindeutig an, dass mehrdeutige Verwendungen von Namen beim Nachschlagen und nicht bei der Deklaration gekennzeichnet werden.)
Es ist interessant, dieses Programm mit einem ähnlichen Programm zu vergleichen, das Gegenstand eines anerkannten gcc-Fehlers ist (leicht modifiziert von diesem Fehlerbericht, um die Parallele klarer zu machen):
%Vor% Das obige Programm ist korrekt; Trotz der Vererbung von Diamanten ist foo
ein statisches Mitglied von A
, daher ist es nicht mehrdeutig. In der Tat kompiliert gcc es ohne Probleme. Das Auskommentieren der beiden Instanzen von using A::foo
, das nichts an foo
ändert, führt jedoch dazu, dass gcc den im Fehlerbericht notierten merklich redundierten Fehler erzeugt. Die beiden using
-Deklarationen in C
zu dekommentieren, was vermutlich den anderen Fehler auslöst, der Gegenstand dieser Frage ist, maskiert den Fehler static function
und bewirkt, dass das Programm erneut kompiliert wird.
clang scheint mit allen möglichen Varianten dieses Programms umzugehen, wofür es sich lohnt.
Beachten Sie, dass eine explizit deklarierte foo(bool)
innerhalb von C
(im ursprünglichen Programm) sich gegenüber% foo(bool)
, die in den C
Bereich gebracht wurden, durch using
Deklarationen durchsetzt. Ich vermute, dass diese beiden Fehler das Ergebnis einer schlechten Buchführung sind, während sie versuchen, die verschiedenen Funktionsdeklarationen in den einzelnen Klassen und ihre individuelle Herkunft zu verfolgen (als eine Folge von using
Deklarationen und Funktionsdeklarationen).
Tags und Links c++ c++11 language-lawyer diagnostics ambiguous-call