Maison >développement back-end >C++ >Comment implémenter une fonction de modèle qui sélectionne son implémentation en fonction de la disponibilité de std::to_string ?
Métaprogrammation : déduction d'une définition de fonction basée sur la disponibilité du type
Dans le contexte de la métaprogrammation de modèles, il devient nécessaire de définir des modèles en fonction de certains critères . Dans ce scénario particulier, l'objectif est de définir un modèle qui sélectionne son implémentation selon que la fonction to_string surchargée est définie pour un type donné.
La tentative initiale consistait à utiliser is_arithmetic comme critère de sélection :
template<typename T> enable_if_t<is_arithmetic<T>::value, string> stringify(T t){ return to_string(t); }
Cependant, to_string peut ne pas être disponible pour les types non arithmétiques, ce qui nécessite un ajout supplémentaire template :
template<typename T> enable_if_t<!is_arithmetic<T>::value, string> stringify(T t){ return static_cast<ostringstream&>(ostringstream() << t).str(); }
Le défi s'est posé lors de la définition des critères de sélection du modèle pour le cas où to_string n'est pas disponible. La tentative suivante a échoué :
template<typename T> enable_if_t<!decltype(to_string(T{})::value, string> (T t){ return static_cast<ostringstream&>(ostringstream() << t).str(); }
Pour résoudre ce problème, nous pouvons exploiter le trait de type void_t introduit par Walter Brown, qui nous permet de définir un trait de type qui vérifie l'existence d'une fonction :
template <typename...> using void_t = void;
En utilisant cela, nous pouvons construire le trait de type souhaité comme suit :
template<typename T, typename = void> struct has_to_string : std::false_type { }; template<typename T> struct has_to_string<T, void_t<decltype(std::to_string(std::declval<T>()))> > : std::true_type { };
Avec ce trait de type, nous pouvons ensuite définir le modèle qui sélectionne son implémentation en fonction de la disponibilité de to_string :
template<typename T> auto stringify(T t) -> std::enable_if_t<has_to_string<T>::value, std::string> { return std::to_string(t); } template<typename T> auto stringify(T t) -> std::enable_if_t<!has_to_string<T>::value, std::string> { return static_cast<ostringstream&>(ostringstream() << t).str(); }
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!