2015-02-24 1 views
1

VS 2013 dit qu'il ne peut pas se spécialiser le modèle de fonction dans le code suivant:VS 2013 ne parvient pas à se spécialiser modèle de fonction de type référence universel et retour en fonction du paramètre de modèle

struct W { }; 

template <class T> 
typename T::result_type 
f (const W & w, T && t) { 
    return 0; 
} 

/* ... */ 
struct V { typedef int result_type; }; 

W w {}; 
V v {}; 
f (w, v); 

Si je remplace typename T::result_type par int ou si Je remplace la référence universelle T&& par T&, il ne se plaint pas.

À mon avis, le code ci-dessus est correct. Est-ce un bug de compilateur, ou est-ce que je fais quelque chose de mal?

Répondre

2

Le compilateur a raison. Les références d'acheminement (1) sont que si elles sont passées une lvalue de type U, elles utilisent U& au lieu de U pour la déduction de type. Puisque v dans votre cas est une lvalue, T est déduit à V&. V& est un type de référence, il n'a pas de type imbriqué (il ne peut même pas en avoir un).

Lorsque vous travaillez avec des références d'expédition, vous devez toujours utiliser std::remove_reference pour obtenir au type sous-jacent:

template <class T> 
typename std::remove_reference<T>::type::result_type 
f (const W & w, T && t) { 
    return 0; 
} 

(1) Depuis CppCon 2014, « référence expédition » a été acceptée comme terme de remplacement "référence universelle", car elle capte mieux l'intention.

+0

Merci beaucoup! Je n'aurais jamais pensé à ça moi-même. J'accepterai votre réponse dès que possible. – JohnB