gcc kann eine variadische Vorlage kompilieren, während clang nicht kann

9

Ich lese einige Folien namens Ein Überblick über C ++ 11 und C ++ 14 vorgestellt von Herrn Leor Zolman. Auf Seite 35 führt er eine Möglichkeit ein, die Summenoperation mit decltype durchzuführen.

%Vor%

Wenn diese Snippets für Sum::sum(1, 2.3, 4, 5); clang-3.6 (von svn) verwendet werden, kann dies nicht mit -std=c++11 / -std=c++1y kompiliert werden, aber gcc-4.9 ist erfolgreich. Natürlich ohne Typabzug für den Rückgabetyp beide kompilieren, aber das beinhaltet Typkonvertierung und kann nicht das erwartete Ergebnis erhalten.

Bedeutet dies also einen Clang-Bug oder liegt das an einer gcc-Erweiterung (in Bezug auf c ++ 11 oder c ++ 14)?

    
Hongxu Chen 09.10.2014, 08:52
quelle

1 Antwort

10

Clangs Verhalten ist korrekt. Dies ist ein GCC-Fehler (und die Behauptung in der Präsentation ist ebenfalls falsch). §3.3.2 [basic.scope.pdecl] / p1,6:

  

1 Der Punkt der Deklaration für einen Namen steht unmittelbar hinter dem   Vollständiger Deklarator (Klausel 8) und vor dessen Initialisierer (falls vorhanden),   außer wie unten angegeben.

     

6 Nach dem Punkt der Deklaration eines Klassenmitglieds kann der Mitgliedsname   im Rahmen seiner Klasse nachgeschlagen werden.

Und §3.3.7 [basic.scope.class] / p1 sagt

  

Die folgenden Regeln beschreiben den Umfang der in Klassen deklarierten Namen.

     

1) Der potentielle Geltungsbereich eines in einer Klasse deklarierten Namens besteht nicht nur   der deklarativen Region nach dem Deklarationspunkt des Namens,   aber auch von allen Funktionskörpern, Standardargumenten,    exception-specifications und brace-or-equal-initializers von   nicht statische Datenelemente in dieser Klasse (einschließlich solcher Dinge in verschachtelten   Klassen).

trailing-return-Typen sind nicht in dieser Liste.

Der abschließende Rückgabetyp ist Teil des Deklarators (§8 [dcl.decl] / p4):

%Vor%

und daher ist die variadische Version von sum nicht innerhalb ihres eigenen trailing-return-type und kann nicht durch Namenssuche gefunden werden.

Verwenden Sie in C ++ 14 einfach den tatsächlichen Rückgabetypabzug (und verzichten Sie auf den nachfolgenden Rückgabetyp). In C ++ 11 können Sie stattdessen eine Klassenvorlage und eine Funktionsvorlage verwenden, die einfach weiterleitet:

%Vor%     
T.C. 09.10.2014, 09:18
quelle

Tags und Links