Questo è causato da due differenti aspetti: CWG CWG issue 2052 e CWG issue 1391.
In primo luogo, CWG 1391. Su incontrando x + a
, il solito nome di ricerca trova, tra le altre sovraccarichi,
template <typename T> double operator+ (T, double);
Template argomento deduzione viene eseguita da corrispondenza T
alla tipologia delle ss di +
, che è double
, quindi questo deduce T
da double
. Il tipo del secondo parametro non contiene parametri di template, quindi non è considerato secondo le regole attuali. Per sicurezza, N::A
non può essere convertito in double
, quindi la specializzazione risultante non è praticabile, ma le regole attuali dicono che la deduzione degli argomenti del modello non interessa questo; che sarà gestito nella risoluzione di sovraccarico.
La proposta di deliberazione CWG 1391, tra le altre cose, aggiunge un nuovo paragrafo alla norma:
Se deduzione riesce per tutti i parametri che contengono template-parametri che partecipano al modello argomento deduzione, e tutti gli argomenti del modello sono esplicitamente specificati, dedotti o ottenuti dagli argomenti del modello di default, i parametri rimanenti sono quindi confrontati con gli argomenti corrispondenti. Per ogni restante parametro P
con un tipo che era non-dipendente prima sostituzione argomenti template esplicitamente specificati, se il corrispondente tesi A non può essere convertito in modo implicito P
, deduzione fallisce. [Nota: I parametri con tipi dipendenti in cui non template-parametri partecipano detrazione template argomento, ei parametri che divennero non-dipendente dovuta alla sostituzione della esplicitamente specificati modello argomenti, sarà controllato durante la risoluzione di sovraccarico. - nota fine]
In altre parole, se un argomento (a
nel nostro caso) corrispondente ad un parametro non dipendente (double
) non può essere convertito nel tipo del parametro, detrazione semplicemente sicuro. Quindi nel nostro caso, la deduzione degli argomenti del template post-CWG1391 fallirà per questo sovraccarico, e tutto andrebbe bene.
Clang implementa le regole attuali, tuttavia, in modo deduzione riesce con T = double
, si verifica la sostituzione, e che incontriamo CWG 2052. Citando l'interessante resoconto da Richard Smith (un dev Clang):
In un esempio come
struct A { operator int(); };
template<typename T> T operator<<(T, int);
void f(A a) { 1 << a; }
argomento template detrazione riesce per il modello dell'operatore, producendo la firma operator<<(int,int)
. Il dichiarazione risultante viene sintetizzato e ha aggiunto al set di sovraccarico, per 14.8.3 [temp.over] paragrafo 1. Tuttavia, questo viola il requisito della 13.5 [over.oper] comma 6,
An la funzione dell'operatore deve essere una funzione membro non statico o essere una funzione non membro che ha almeno un parametro il cui tipo è una classe, un riferimento a una classe, un'enumerazione o un riferimento a un'enumerazione .
Questo non è un contesto SFINAE, quindi il programma è mal formato, piuttosto rispetto alla selezione dell'operatore integrato.
In questo caso, non c'è conversione, in modo che il dedotto operator+(double, double)
è in realtà non è praticabile, ma i candidati non vitali non sono eliminati fino a quando si è creato il set di candidato, e qui la costruzione del set candidato sta causando un errore hardware .
La proposta di risoluzione per CWG 2052 renderà questo caso SFINAE - anche facendo funzionare il codice originale. Il problema è che anche qui Clang sta implementando la versione attuale dello standard.
Da quell'errore, sembra essere stato trovato da ADL. Non sei sicuro di cosa si stia lamentando anche se – xcvr
Nota che il tuo programma di test ha un comportamento indefinito, dal momento che 'x' non è inizializzato. –
@KerrekSB * Stai * riproducendo perché stai usando gcc mentre puoi compilarlo. [Clang can not] (http://coliru.stacked-crooked.com/a/bd4cfc7eb1cc02d7). – 0x499602D2