2015-06-26 13 views
9

Si consideri il seguente codice:intesa modello argomento deduzione

#include <vector> 

template <typename T> 
using v_itt = typename std::vector<T>::iterator; 

template <typename T> 
void foo(v_itt<T>){ } 

int main() { 
    typename std::vector<long>::iterator i = std::vector<long>().begin(); 
    foo(i); //candidate template ignored: couldn't infer template argument 'T' 
} 

DEMO

Cosa c'è di sbagliato con il codice? Ho pensato che lo T avrebbe dovuto essere dedotto a long. C'è un modo per risolverlo in qualche modo?

risposta

5
typename std::vector<T>::iterator 

iterator (un tipo dipendente) si è non desumibile nel codice dal momento che è in un nome specificatore nidificato e lo standard dice

§14.8.2.5/4

In alcuni contesti, tuttavia, il valore non partecipa alla deduzione dei tipi, ma utilizza invece i valori degli argomenti del modello che sono stati dedotti altrove o esplicitamente specificati. Se un parametro modello viene utilizzato solo in contesti non dedotti e non è specificato esplicitamente, la deduzione argomento modello non riesce.

e §14.8.2.5/5

I contesti non dedotta sono:

- Il nested-nome-identificatore di un tipo che è stato specificato con un qualificato-id.

quindi questo è un contesto non dedotto.

possibili soluzioni:

  1. passare un riferimento vettore al posto di un iteratore
  2. tag utilizza il dispacciamento e compile time assertions per verificare l'iteratore
3

mi piacerebbe solo aggiungere una possibile soluzione 3 alla risposta di Marco:

#include <vector> 

template<typename T> 
void real_foo(typename std::vector<T>::iterator){} 

template <typename T> 
void foo(T i){ real_foo<typename decltype(i)::value_type>(i); } 

int main() { 
    std::vector<long> v; 
    foo(v.begin()); 
} 
+2

Buona soluzione: ancora meno prolisso. Grazie Paolo. –

+0

Bel trucco, sì. Grazie. –

+2

@MarcoA. Beh, non è molto elegante perché si basa solo sull'errore di compilazione che non fornisce alcun messaggio all'utente, ma è solo un altro modo di fare la stessa cosa :) –