2012-04-30 13 views
6

Betrachten Sie das folgende Programm:Wird die Substitution an einem variadischen Parameter-Paketyp durchgeführt, wenn das Paket leer ist?

#include <type_traits> 

enum class dummy {}; 
template <typename T> 
using EnableIf = typename std::enable_if<T::value, dummy>::type; 
template <typename T> 
using DisableIf = typename std::enable_if<!T::value, dummy>::type; 

template <typename T> 
struct dependent_true_type : std::true_type {}; 

template <typename T, 
      EnableIf<dependent_true_type<T>>...> 
std::true_type f(); 
template <typename T, 
      DisableIf<dependent_true_type<T>>...> 
std::false_type f(); 

static_assert(decltype(f<int>())::value, ""); 

int main() {} 

GCC 4.7 glady dieses Programm akzeptiert. Mein letzter Claim 3.1 Build behauptet, dass der Aufruf an f mehrdeutig ist.

test.c++:22:24: fatal error: call to 'f' is ambiguous 
static_assert(decltype(f<int>())::value, ""); 
         ^~~~~~ 
test.c++:17:16: note: candidate function [with T = int, $1 = <>] 
std::true_type f(); 
      ^
test.c++:20:17: note: candidate function [with T = int, $1 = <>] 
std::false_type f(); 
       ^
1 error generated. 

Es tut das Programm akzeptieren, wenn ich f<int, dummy{}>() schreiben.

Es scheint, dass clang den Typ des Parameterpakets nicht berücksichtigt, wenn das Paket leer ist, was dazu führt, dass es nicht aus dem Kandidatensatz entfernt wird. GCC scheint eine Substitution des Parameter-Pakettyps durchzuführen, selbst wenn das Paket leer ist, und da die Substitution für eine Überladung fehlschlägt, gibt es keine Mehrdeutigkeit.

Welche der beiden ist richtig?

Antwort

7

Ich glaube, ich habe das relevante Stück Standard gefunden. §14.8.2p7 sagt:

Die Substitution in allen Formen und Ausdrücken auftritt, die in dem Funktionstyp und in Template-Parametern Erklärungen verwendet.

Da EnableIf<dependent_true_type<T>> wird in einer Vorlage Parameter Deklaration verwendet wird, sollte die Substitution auftreten, und dies ist a bug in clang.

+0

Könnten Sie bitte die PR kommentieren und Ihren Testfall hinzufügen? Ihr Testfall ist kritischer imho, weil er während der Argumentableitung auftritt (mein Testfall vermisst eine Substitution nur am Ende nach dem Argumentabzug) und weil der Clam von gcc abweicht. –

+0

@Johannes Fertig. –

+0

danke Kumpel. . –