Maison >développement back-end >C++ >Comment puis-je restreindre les types de modèles en C comme le mot clé « extends » de Java ?

Comment puis-je restreindre les types de modèles en C comme le mot clé « extends » de Java ?

DDD
DDDoriginal
2024-12-20 11:39:101068parcourir

How Can I Restrict Template Types in C   Like Java's `extends` Keyword?

Contraindre les types de modèles en C

En Java, vous pouvez restreindre une classe générique pour n'accepter que les types qui étendent une classe de base spécifiée à l'aide de l'option étend le mot-clé. Existe-t-il un mot-clé similaire en C à cet effet ?

Équivalent C

C n'a pas d'équivalent direct au mot-clé extends de Java pour les contraintes de modèle. Cependant, C 11 propose des mécanismes alternatifs pour obtenir un effet similaire.

Approche C 11 utilisant les traits de type

Dans C 11, vous pouvez utiliser le trait std::is_base_of du en-tête pour vérifier si un type est dérivé d’un autre type. Voici un exemple :

#include <type_traits>

template<typename T>
class observable_list {
    static_assert(std::is_base_of<list, T>::value, "T must inherit from list");

    // ...
};

Cet exemple définit une classe de modèle observable_list qui n'accepte que les types qui héritent de la classe list. Cependant, il est important de noter que des modèles trop contraignants peuvent limiter leur flexibilité et peuvent ne pas être idéaux en C.

Approche alternative : contraintes basées sur les traits

Une approche alternative implique la création de traits personnalisés pour contraindre les types en fonction d'exigences spécifiques. Par exemple, vous pouvez définir un trait pour les types avec des fonctions membres ou des typedefs spécifiques :

struct has_const_iterator {
    template<typename T>
    static bool test(...) { return false; }
};

template<typename T>
struct has_const_iterator<T, Void<typename T::const_iterator>> {
    static bool test(...) { return true; }
};

struct has_begin_end {
    template<typename T>
    static bool test(...) { return false; }

    template<typename T, typename Begin, typename End>
    static auto test(int) -> decltype(std::declval<const T&>().begin(), std::declval<const T&>().end()) { return true; }
};

En utilisant ces traits, vous pouvez contraindre observable_list comme suit :

class observable_list {
    static_assert(has_const_iterator<T>::value, "Must have a const_iterator typedef");
    static_assert(has_begin_end<T>::value, "Must have begin and end member functions");

    // ...
};

Cette approche offre une meilleure flexibilité et retour d'erreur en vous permettant de définir des contraintes spécifiques en fonction de vos besoins.

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!

Déclaration:
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