Le guide alla deduzione del modello sono modelli associati a una classe modello che indicano al compilatore come tradurre un insieme di argomenti del costruttore (e i loro tipi) in parametri del modello per la classe.
L'esempio più semplice è quello di std::vector
e il suo costruttore che accetta una coppia di iteratori.
template<typename Iterator>
void func(Iterator first, Iterator last)
{
vector v(first, last);
}
Il compilatore ha bisogno di capire che cosa vector<T>
's T
tipo sarà. Sappiamo qual è la risposta; T
dovrebbe essere typename std::iterator_traits<Iterator>::value_type
. Ma come facciamo a dirlo al compilatore senza dover digitare vector<typename std::iterator_traits<Iterator>::value_type>
?
Utilizzi una guida alle detrazioni:
template<typename Iterator> vector(Iterator b, Iterator e) ->
vector<typename std::iterator_traits<Iterator>::value_type>;
Questo dice al compilatore che, quando chiami un vector
costruttore che corrisponde a quel modello, dedurrà la vector
specializzazione usando il codice a destra di ->
.
Hai bisogno di guide quando la deduzione del tipo dagli argomenti non è basata sul tipo di uno di quegli argomenti. L'inizializzazione di un vector
da un initializer_list
utilizza esplicitamente vector
's T
, quindi non ha bisogno di una guida.
Il lato sinistro non specifica necessariamente un costruttore effettivo. Il modo in cui funziona è che, se si utilizza la deduzione del costruttore del modello su un tipo, corrisponde agli argomenti passati rispetto a tutte le guide alla detrazione (i costruttori effettivi del modello principale forniscono guide implicite). Se c'è una corrispondenza, la usa per determinare quali argomenti del modello fornire al tipo.
Ma una volta che la deduzione è stata eseguita, una volta che il compilatore ha individuato i parametri del modello per il tipo, l'inizializzazione dell'oggetto di quel tipo procede come se nulla di tutto ciò accadesse. Cioè, la guida alla detrazione selezionata non deve necessariamente corrispondere al costruttore selezionato.
Ciò significa anche che puoi utilizzare le guide con aggregati e inizializzazione di aggregati:
template<typename T>
struct Thingy
{
T t;
};
Thingy(const char *) -> Thingy<std::string>;
Thingy thing{"A String"};
Quindi le guide alle detrazioni vengono utilizzate solo per capire il tipo da inizializzare. Il processo effettivo di inizializzazione funziona esattamente come prima, una volta effettuata tale determinazione.