2014-05-01 9 views
6

gcc-4.8 akzeptiert diesen Code, aber ist es nicht falsch, da das Nicht-Typ-Parameterpaket void... entspricht, was illegal ist?ist nicht nicht-Typ-Parameter-Pack, das zu "void ..." ungültig bewertet?

template <typename T, 
      typename std::enable_if<std::is_integral<T>::value>::type...> 
void test(T) {} 

Ich versuchte dies mit clang-3.5 auch das akzeptiert es auch. Ist das ein Compiler Bug, oder verstehe ich etwas falsch?

Vollständiger Testcode, der nicht-leere Parameterpakete verwendet, um enable_if zu vereinfachen. Dies ist fast das gleiche wie das, was in Flaming Dangerzone's Remastered enable_if ist, außer nach der Substitution wird das Paket void....

#include <type_traits> 

template < typename C > 
using enable_if = typename std::enable_if<C::value>::type ; 

template < typename T, enable_if<std::is_integral<T>>... > 
void test(T){} // #1 

template < typename T, enable_if<std::is_floating_point<T>>... > 
void test(T){} //#2 

int main() 
{ 
    test(0); // calls #1 
    test(0.0); // calls #2 
    return 0; 
} 

gcc-4,8 kompiliert den obigen Code gerade gut. Klang ist nicht, aber das ist, weil es einen anderen Fehler http://llvm.org/bugs/show_bug.cgi?id=11723 hat.

+1

Ich denke, es ist illegal. Siehe Abschnitt [temp.param] 14.1/7 des Standards: "Ein nicht typisierter Template-Parameter darf nicht als Gleitkomma, Klasse oder Void-Typ deklariert werden." – Constructor

+0

Sie sollten eigenständigen Code bereitstellen. Alles, was ich sagen kann, ist, dass Ihr Code nicht kompiliert wird, weil die fehlenden includes und main fehlen. –

+2

@ JohannesSchaub-litb Siehe [ein einfaches Beispiel] (http://ideone.com/hxuKmJ), das das Problem reproduziert. – Constructor

Antwort

3

Beide Code-Schnipsel Sie keinen Sinn vorgesehen sind, da Sie keine Expansion Pack ohne einem nicht ausgedehnten Parameter Pack haben: §14.5.3/5:

Das Muster einer Expansion Pack wird Benennen Sie ein oder mehrere Parameter-Packs, die nicht durch eine Nested-Pack-Erweiterung erweitert werden. Solche Parameterpakete heißen nicht expandierte Parameterpakete im Muster.

Zurück zum eigentlichen Problem: Wenn Sie tatsächlich verwendeten eine richtige Expansion Pack und Sie instanziiert diese Expansion Pack mit einem nicht leeren Parametersatz, die Regel in §14.1/7 gilt, weil offensichtlich ein nicht-Typ Vorlagenparameter kann nicht mit void type deklariert werden.

Solange diese Packexpansion nicht mit einem nicht leeren Parameterpaket instanziiert wird, wird keine Regel verletzt, da keine Parameterdeklaration erfolgt. :)