Penso che GCC abbia ragione e la tua tecnica sia corretta. Fondamentalmente, poiché l'argomento di tipo per C
è specificato esplicitamente, la domanda è se:
a. la sostituzione di C
in qualsiasi altro punto nella firma del modello di funzione avviene prima, quindi viene eseguita la deduzione del tipo (che dovrebbe comportare un errore di sostituzione); oppure
b. la deduzione di tipo viene eseguita per prima, quindi viene eseguita la sostituzione (che non comporterebbe un errore di sostituzione, poiché il pacchetto di argomenti corrispondente sarebbe vuoto e quindi non ci sarebbe alcuna sostituzione da eseguire).
Sembra che GCC assuma (1), mentre Clang assume (2). Paragrafo 14.8.2/2 del C++ 11 specifica standard:
Quando viene specificato un elenco di modelli argomento esplicito, gli argomenti di template deve essere compatibile con la lista dei parametri modello e deve risultare in un tipo di funzione valida come descritto sotto; altrimenti digitare la detrazione non riesce. Specificamente, le seguenti operazioni vengono eseguite quando si valuta un modello lista di argomenti esplicitamente specificato rispetto ad un determinato modello di funzione:
- Gli argomenti del template specificati devono corrispondere ai parametri del modello in natura (per esempio, tipo, non-type , Modello ). Non ci devono essere più argomenti di quanti siano i parametri a meno che almeno un parametro sia un pacchetto di parametri template e ci sia un argomento per ciascun parametro non-pack. In caso contrario, la deduzione di tipo non riesce.
- Non di tipo argomenti devono corrispondere i tipi dei parametri del modello non-tipo corrispondente, oppure devono essere convertibili ai tipi di parametri non corrispondenti di tipo come specificato in 14.3.2, altrimenti tipo detrazione non riesce.
- I valori dell'argomento modello specificato vengono sostituiti ai parametri modello corrispondenti come specificato sotto.
il seguente paragrafo dice poi:
volta eseguita questa sostituzione, le regolazioni tipo di parametro funzione descritti in 8.3.5 vengono eseguite. [...]
Inoltre, comma 14.8.2/5 specifica:
I risultanti sostituito e regolato funzione tipo viene utilizzato come tipo di modello di funzione di template argomento deduzione . [...]
Infine, il paragrafo 14.8.2/6 va come segue:
In certi punti del processo detrazione modello argomento, è necessario prendere un tipo di funzione che fa uso dei parametri del modello e sostituire i parametri del modello con gli argomenti del modello corrispondente . Questa operazione viene eseguita all'inizio della deduzione degli argomenti del modello quando qualsiasi argomento modello specificato esplicitamente viene sostituito nel tipo funzione e nuovamente alla fine della deduzione argomento modello quando gli argomenti del modello che sono stati dedotti o ottenuti dagli argomenti predefiniti sono sostituiti .
Tutto ciò sembra implicare che viene eseguita la prima sostituzione, quindi la deduzione argomento modello. Quindi, in entrambi i casi si verifica un errore di sostituzione e uno dei due modelli deve essere scartato dal set di sovraccarico.
Sfortunatamente, non sembra esserci una specifica chiara su quale debba essere il comportamento quando gli argomenti dei template vengono dedotti piuttosto che essere esplicitamente specificati.
Questo si applica solo quando specifichiamo esplicitamente l'argomento e non lo deduciamo? (cioè, se avessi reso la funzione prendi 'T const &', quindi passassi '7' su di esso, il trucco non sarebbe più legale?) – Yakk
@Yakk: In tal caso non sono esattamente sicuro, ma ho letto attraverso l'intero 14.8.2 diverse volte e mi sembra che lo Standard non specifichi quale dovrebbe essere il comportamento –