Quello che dico sotto (sotto OLD POST ) dovrebbe essere vero fino a un certo punto, ma il vero problema con questo è che SFINAE è usato in modo errato, quindi non sono più sicuro che questo sia un bug in gcc.
Una dichiarazione alias deve sempre avere successo, non è possibile SFINAE lì, dal momento che non è una dichiarazione di classe o di funzione o specializzazioni (questo ha senso, dal momento che non è possibile specializzare gli alias). Se la dichiarazione di alias non riesce, il programma è mal formato. Quindi il compilatore può presumere che non si verificherà mai che la dichiarazione di alias non avrà successo fino a quando non la forzerai a creare un'istanza di tale modello.
Quindi è perfettamente accettabile per il compilatore pensare che ciò avvenga sfinae_v_t<T,...>
sempre T
, poiché ciò accadrà, quando il programma non è mal formato. Quindi vedrà che in tutti i casi in cui il programma non è mal formato, la specializzazione parziale non è specializzata e come tale ti dirà che questo è mal formato. (Questo è ciò che fa clang).
Non penso che il compilatore sia costretto a farlo. E se non lo fa, e pensa semplicemente "Ok, sfinae_v_t
è un tipo, qualunque cosa", allora non è ovvio che si tratta di una dichiarazione. Quindi penso che fino a quando non avremo un'istanza di uno di essi non ci sia nulla di male nel non gettare un errore.
Ma quando creiamo un'istanza dovrebbe esserci il problema di avere una dichiarazione o che il programma è mal formato a causa std::enable_if
dell'argomento template. GCC dovrebbe prenderne almeno uno ma nessuno dei due.
Anche questo non si applica assolutamente all'esempio più semplice senza std::enable_if
. Quindi penso ancora che si tratti di un bug in GCC, ma sono abbastanza stordito da non poterlo più dire con certezza. Direi solo che qualcuno dovrebbe segnalarlo come un bug e lasciare che le persone di gcc ci pensino.
POST VECCHIO
Questo è un bug in gcc. Lo standard ci fornisce le regole per convertire un modello di classe in modelli di funzione. Un modello di classe è più specializzato di un altro se la sua funzione precede l'altra nell'ordinamento parziale del modello di funzione.
Ho creato le funzioni qui e ora gcc afferma che chiamarle è ambigua, quindi dovrebbe anche dire che i modelli di classe sono ugualmente specificati.
Nota: leggendo attentamente lo standard, il compilatore nella mia testa è d'accordo con Clang.