gcc vs. clang, msvc und icc: Ist dieser Funktionsaufruf mehrdeutig?

9

Alle Compiler, die ich in die Hände kriege, stimmen darin überein, dass das in Ordnung ist:

%Vor%

Der folgende Code (mit einem führenden Vorlagenparameter, der nicht aus den Funktionsparametern abgeleitet werden kann) ist jedoch gemäß gcc:

mehrdeutig %Vor%

Auf der anderen Seite sind clang, msvc und icc sehr zufrieden damit.

Welcher Compiler ist richtig?

Verweise auf die jeweiligen Abschnitte des Standards bevorzugt.

    
Rumburak 02.09.2016, 06:57
quelle

2 Antworten

4

Dies ist Kernproblem 200 .

  

Die Beschreibung, wie die partielle Reihenfolge der Template-Funktionen ist   bestimmt in 14.5.6.2 [temp.func.order] Absätze 3-5 nicht machen   irgendeine Bestimmung für nicht-entkoppelte Schablonenparameter. Zum Beispiel, die   Funktionsaufruf im folgenden Code ist mehrdeutig, obwohl einer   Vorlage ist "offensichtlich" spezialisierter als die andere:

%Vor%      

Der Grund ist, dass keine Funktionsparameterliste den Template-Parameter T ableiten kann; beide Ableitungen scheitern, also auch nicht   Vorlage gilt als spezialisierter als die andere und die   Funktionsaufruf ist mehrdeutig.

Die Auflösung des Kernproblems 214 , auf die sich dieser Artikel bezieht, wurde eingeführt [temp.deduct.partial]/11 :

  

In den meisten Fällen müssen alle Template-Parameter Werte haben, damit der Abzug erfolgreich ist, aber für partielle Bestellzwecke kann ein Template-Parameter ohne Wert bleiben, vorausgesetzt, er wird nicht in den zur partiellen Sortierung verwendeten Typen verwendet / strong>.

Offensichtlich ist die Umsetzung dieses Wortlauts durch den GCC fehlerhaft, sobald die Packs ins Spiel kommen.

    
Columbo 02.09.2016, 15:24
quelle
0

Ich glaube, dass GCC falsch ist und CLANG hier korrekt ist. Ich werde versuchen, meinen Anspruch unten zu rechtfertigen:

Gemäß dem Standard §14.8.3 / p1 Überladungsauflösung [temp.over] ( Betonung meiner ) :

  

Eine Funktionsvorlage kann entweder von (nicht Vorlage) überladen werden   Funktionen seines Namens oder durch (andere) Funktionsvorlagen desselben   Name. Wenn ein Aufruf an diesen Namen geschrieben wird (explizit oder implizit)   mit der Operatorschreibweise), Vorlagenargumentabzug (14.8.2)   und Überprüfung von expliziten Vorlagenargumenten (14.3) durchgeführt werden   für jede Funktionsvorlage, um die Vorlagenargumentwerte zu finden (wenn   any), die mit dieser Funktionsvorlage verwendet werden können, um eine Instanz zu instanziieren   Funktionsschablonenspezialisierung, die mit dem Aufruf aufgerufen werden kann   Argumente. Für jede Funktionsvorlage, wenn das Argument Abzug und   Überprüfung gelingt, die Template-Argumente (abgeleitet und / oder explizit)   werden verwendet, um die Deklaration einer einzelnen Funktionsvorlage zu synthetisieren   Spezialisierung, die zu den Kandidatenfunktionen hinzugefügt wird   Überladungsauflösung verwendet. Wenn für eine gegebene Funktionsvorlage   Argumentabzug schlägt fehl oder die synthetisierte Funktionsvorlage   Spezialisierung wäre schlecht gebildet, keine solche Funktion wird hinzugefügt   Satz von Kandidatenfunktionen für diese Vorlage. Der komplette Satz von   Kandidatenfunktionen umfassen alle synthetisierten Deklarationen und alle   der nicht überladenen Template-Funktionen desselben Namens. Das   synthetisierte Deklarationen werden wie alle anderen Funktionen in der   Rest der Überladungsauflösung, außer wie ausdrücklich in   13.3.3. 144

     

[Beispiel:

%Vor%      

144) Die Parameter der Spezialisierung von Funktionsvorlagen enthalten   keine Template-Parametertypen Die Anzahl der zulässigen Conversions   Argumente sind begrenzt, weil der Argument-Deduktionsprozess erzeugt   Funktionsvorlagen mit Parametern, die entweder dem Aufruf entsprechen   Argumente genau oder unterscheiden sich nur in Wege, die durch die überbrückt werden können   erlaubte begrenzte Umwandlungen. Nicht abgeleitete Argumente erlauben das volle   Bereich der Konvertierungen. Beachten Sie auch, dass 13.3.3 angibt, dass a   Nicht-Template-Funktion wird gegenüber einer Vorlage bevorzugt   Spezialisierung, wenn die beiden Funktionen ansonsten gleich gut sind   Kandidaten für eine Überlastungsübereinstimmung.

Aus dem Obigen ergibt sich, dass explizite Template-Argumente überprüft werden und wenn die Überprüfung erfolgreich ist, wird dann eine Spezialisierung synthetisiert, die zu den Kandidatenfunktionen für die Überladungsauflösung hinzugefügt wird. Daher ist die Tatsache, dass Sie explizit X angeben, für den Prozess irrelevant.

Auch aus dem C ++ Standard §13.3.3 / p1.7 Beste lebensfähige Funktion [over.match.best] :

  

F1 und F2 sind Funktionsvorlagenspezialisierungen und die Funktion   Vorlage für F1 ist spezialisierter als die Vorlage für F2   nach den in 14.5.6.2 beschriebenen Teilordnungsregeln.

Nun von §14.5.6.2 / p3 Partielle Anordnung der Funktionsvorlagen [temp.func.order] wir bekommen, dass in teilweise Anordnung Parameter Packs auch ins Spiel kommen, also kein Problem auch hier.

Jetzt:

%Vor%

ist spezialisierter als:

%Vor%

Rufen Sie daher an:

%Vor%

ist nicht mehrdeutig.

Basierend auf dem oben genannten glaube ich, dass dies ein GCC-Bug ist.

    
101010 02.09.2016 08:22
quelle