2010-10-30 9 views
4
template<typename T> 
std::istream & read(std::istream & istr, typename std::enable_if<std::is_pod<T>::value, T>::type & value) 
{ 
    return istr.read(reinterpret_cast<char*>(&value), sizeof(T)); 
} 

int main() 
{ 
    int x; 
    read(cin, x); // error here 
} 


error C2783: 'std::istream &read(std::istream &,std::enable_if<std::tr1::is_pod<_Ty>::value,T>::type &)' : could not deduce template argument for 'T' 

Cela fonctionne si je spécifie lire <int>. Y at-il un moyen de l'obtenir pour déduire le type de l'argument?Pourquoi le type ne peut-il pas être déduit dans cette fonction de modèle?

Répondre

15
template<typename T> 
std::istream & read(std::istream & istr, T value, 
        typename std::enable_if<std::is_pod<T>::value>::type* = 0) 
{ 
    return istr.read(reinterpret_cast<char*>(&value), sizeof(T)); 
} 

Ou

template<typename T> 
typename std::enable_if<std::is_pod<T>::value, std::istream>::type & 
read(std::istream & istr, T value) 
{ 
    return istr.read(reinterpret_cast<char*>(&value), sizeof(T)); 
} 

La raison pour laquelle le vôtre ne fonctionne pas est parce qu'il ne suffit pas pour déterminer T si vous connaissez le type de l'argument. Et si enable_if serait un modèle comme celui-ci?

template<int N, typename T> struct A { typedef int type; }; 

Toute T en <std::is_pod<T>::value, T> le ferait. En général, un type de paramètre de fonction formé par ...T...::type est appelé un contexte non déduit et ne peut pas être utilisé pour déduire T.

+0

Parfait, merci. –

+0

Vous dites "en général", y a-t-il un cas spécifique autrement? – GManNickG

+0

@GMan Je ne peux pas penser à un autre cas. Fixé. –