J'essaie de définir une fonction à l'aide de modèles et je veux que le nom de type soit int ou anEnum (une énumération spécifique que j'avais définie). J'ai essayé ce qui suit mais j'ai échoué:
template <int | anEnum T> // or <int T, anEnum T> or <int, anEnum T>
bool isFunction(const T &aVariable){}
Ce que j'essaie de faire, c'est d'utiliser des modèles, au lieu de définir deux fonctions surchargées. Je préfère que la fonction soit appelée comme suit, sans que le programmeur doive considérer le type
isFunction(aVariable) // and not isFunction<int> (aVariable) nor isFunction<anEnum> (aVariable)
Fondamentalement, je veux que cette fonction soit basée sur des modèles pour les types int et aNum. J'ai cherché cela, mais je n'ai pas pu trouver la réponse. Que puis-je manquer? Merci,
false
pour d'autres types ou ne pas instancier la fonction pour d'autres types.Réponses:
En plus de la réponse non C ++ 20, si vous êtes par hasard en mesure d'utiliser C ++ 20 et ses
concepts
fonctionnalités, je vous suggère l'implémentation suivante:Démo
MISE À JOUR
Selon le commentaire de @RichardSmith , voici une approche plus évolutive et réutilisable:
la source
template<typename T, typename ...U> concept one_of = (std::is_same_v<T, U> || ...);
template<one_of<int, MyEnum> T> bool isFunction(T const& aVariable) {
Il y a deux façons d'y parvenir. Tous impliquent l'utilisation de l'en-
type_traits
tête. Vous pouvez par exemple affirmer statiquement les types en question dans le corps de la fonction.Ou, si vous devez considérer cette fonction parmi d'autres surcharges, une technique SFINAE peut être utilisée.
Cela supprimera la fonction d'un ensemble de surcharge avant son appel si les types ne correspondent pas. Mais si vous n'avez pas besoin de ce comportement, une assertion statique permet un message d'erreur plus convivial pour le programmeur.
la source
Et cette solution? Un code avec la fonction sera compilé si le type T satisfait vos exigences. Sinon, l'assertion statique a échoué.
la source
isFunction(std::string_view)
). La signature sera toujours une correspondance valide, mais l'instanciation provoque une erreur.J'ai amélioré la réponse https://stackoverflow.com/a/60271100/12894563 . 'Si constexpr' peut aider dans cette situation:
isFunction (1L) échouera car il n'y a pas de fonction surchargée ou de branche 'if constexpr'.
MISE À JOUR: Correction manquée
https://godbolt.org/z/eh4pVn
la source
static_assert(false, ...)
est NDR mal formé, sans même être utilisé. Si vous avez de la chance, votre compilateur vous le dira tout de suite, comme Clang le fait, godbolt.org/z/m_Gk9n