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 ?

Comment implémenter une fonction de modèle qui sélectionne son implémentation en fonction de la disponibilité de std::to_string ?

Linda Hamilton
Libérer: 2024-11-09 08:25:02
original
660 Les gens l'ont consulté

How to Implement a Template Function That Selects Its Implementation Based on the Availability of 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);
}
Copier après la connexion

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();
}
Copier après la connexion

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();
}
Copier après la connexion

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;
Copier après la connexion

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 { };
Copier après la connexion

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&amp;>(ostringstream() << t).str();
}
Copier après la connexion

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!

source:php.cn
Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Derniers articles par auteur
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal