2017-09-15 13 views
0

Je voudrais savoir quelles sont les principales différences entre les méthodes suivantes. Y a-t-il un cas où l'un des deux causerait des problèmes si std::to_string est défini?Avoir seulement une spécialisation de modèle unique utile?

include <string> 
using namespace std; 


enum class eColor 
{ 
    Red 
}; 

void to_string(eColor color) 
{ 
} 

template<typename C = eColor) 
void to_string(C color) 
{ 
} 



int main() 
{ 
    to_string(eColor::Red); // assume only one of the above is defined 
    return 0; 
} 

Y a-t-il un cas où l'un des éléments ci-dessus devrait être préféré?

+0

Votre modèle va créer un gâchis. Voir https://stackoverflow.com/questions/1452721/why-is-using-namespace-std-considered-bad-practice – juanchopanza

+0

Aussi, pourquoi voudriez-vous un modèle? – juanchopanza

+0

Je ne vois pas beaucoup de points pour la version sur gabarit. Mais votre exemple est trop simplifié, vous devriez également montrer la mise en œuvre. – user0042

Répondre

0

En dépit des choses comme la pollution inutile de l'espace de noms par votre directive en utilisant ce qui est particulièrement bizarre si vous prévoyez d'utiliser des noms comme to_string:

fonctions modèle déduisent automatiquement leur argument modèle. Donc, ce qui suit serait tout à fait valable:

int main(int argc, const char * argv[]) { 
    to_string(eColor::Red); 
    to_string("Hey"); 
    to_string(42); 
    return 0; 
} 

Donc, si vous prévoyez vraiment taylor votre fonction pour un type dédié, vous êtes pour certains messages d'erreur vraiment intéressant ou pire encore aucun message d'erreur combinée à un comportement indésirable.

La version de la fonction empêchera au moins certains des cas erronés. (Il acceptera quand même le 42 bien qu'il y ait une conversion implicite).

1

Votre fonction to_string (couleur eColor) n'est pas vraiment une spécialisation de template car elle manque le template <> before definition. Le compilateur le traite donc comme une fonction entièrement définie, et non comme un modèle à générer avec un type concret. Cela signifie que cette fonction sera toujours utilisée tant que le compilateur peut correspondre à la liste des arguments.