2015-08-15 10 views
14
#include <tuple> 

template<int I> 
struct A {}; 

template<int I, typename... T> 
void f(A<I>, std::tuple<T *...>) {} 

template<typename... T> 
void f(A<0>, std::tuple<T *...>) {} 

int main() 
{ 
    f(A<0>{}, std::tuple<char*, int*, float*>{}); 
} 

Il secondo sovraccarico di f non è più specializzato? g ++ 4.9.2 dice che la chiamata è ambigua, clang 3.6.0 lo accetta. Quale compilatore ha ragione?Non è `void f (A <0>, tupla <T *...>)` più specializzato di `void f (A <I>, tupla <T *...>)`?

È interessante notare che se si modifica std::tuple<T *...> in std::tuple<T...>, g ++ funziona correttamente, cosa che non capisco.

+0

MSVC 2013 è soddisfatto anche di questo :) –

+0

Sospetto che gcc sia errato, ma potrebbe esserci qualcosa di oscuro sui parametri del modello di valore (lo standard tende ad essere bizzarro attorno ad essi). Puoi effettuare il repo senza usare valori? – Yakk

+0

[clang] (http://clang.llvm.org) è anche OK con il codice. –

risposta

5

Secondo le regole attuali, il secondo sovraccarico è più specializzato. Alcune specializzazioni A<@> con un valore sintetizzato @ non possono essere abbinate a A<0>, ma A<0> può essere abbinato a A<I> (con I=0). L'asimmetria di questa prima coppia è decisiva. Se si utilizza T o T* poiché il modello nel secondo parametro non è rilevante, la deduzione ha esito positivo in entrambi i modi per quella coppia.

L'errore persiste nel trunk ed è stato segnalato da @Barry come 67228.

+0

Nota: la risoluzione CWG 1391 potrebbe rendere ambiguo questo aspetto. Però non sono sicuro di questo. – Columbo

+0

Sì, la risoluzione non è del tutto giusta, penso. Controlla la risposta di bogdan [qui] (http://stackoverflow.com/a/31735126/2069064), penso che abbia alcune buone idee su come risolvere effettivamente le diciture. – Barry

+3

Ho inviato [67228] (https://gcc.gnu.org/bugzilla/show_bug.cgi?id=67228). – Barry

Problemi correlati