Betrachten Sie den folgenden Code:
%Vor% Hier stellt Vector
eine Klasse dar, die in einer Bibliothek eines Drittanbieters definiert ist, und std::array
ist dafür bekannt, seine Elementanzahl als std::size_t
zu übernehmen.
Ich habe versucht, dies mit clang-3.6 und g ++ - 5.1 zu kompilieren. Clang arbeitete ohne Beanstandung, während g ++ den folgenden Fehler gibt:
%Vor% Ich kann das umgehen, indem ich eine Umwandlung von N
in std::size_t
im zweiten Parameter von doWork()
oder Aufruf von doWork<3>()
tue, aber das würde mich nicht weiterbilden.
Also frage ich lieber zuerst: Welcher Compiler ist hier richtig? Mache ich wirklich etwas falsch im Code (also ist clang zu permissiv), oder ist es wirklich gültig C ++ (so dass g ++ einen Bug hat)?
Ich glaube, gcc ist hier korrekt, wenn wir zum Entwurf des C ++ 11-Standardabschnitts 14.8.2.5
[temp.educt.type] gehen, heißt es:
Wenn in der Deklaration einer Funktionsvorlage mit einem Nicht-Typ Template-Parameter, der Nicht-Typ Template-Parameter wird in einem verwendet Ausdruck in der Funktion Parameter-Liste und, wenn die entsprechende Template-Argument wird abgeleitet, der Template-Argumenttyp muss übereinstimmen der Typ des Template-Parameters genau, außer dass a Template-Argument abgeleitet von einer Array-Grenze kann von jedem Integral sein type.144 [Beispiel:
%Vor%[...]
und wir können sehen, ob wir Ihren Code zu diesem ändern:
%Vor%gcc gibt keinen Fehler aus und klingelt auch nicht.
Wenn wir dieses Beispiel versuchen:
%Vor%clang erzeugt jetzt einen Fehler ( live sehen ):
%Vor%Ihr ursprünglicher Fall bricht auch, wenn wir die Parameterreihenfolge vertauschen:
%Vor%Tags und Links c++ clang c++11 language-lawyer g++