Maison > développement back-end > C++ > Comment puis-je restreindre les types de modèles en C à un héritage ou à des fonctionnalités spécifiques ?

Comment puis-je restreindre les types de modèles en C à un héritage ou à des fonctionnalités spécifiques ?

Barbara Streisand
Libérer: 2024-12-31 04:58:09
original
180 Les gens l'ont consulté

How Can I Restrict Template Types in C   to Specific Inheritance or Functionality?

Comment contraindre un modèle à n'accepter que des types spécifiques en C

En Java, les classes génériques peuvent être définies pour accepter uniquement les types qui héritent d'une classe spécifique :

public class ObservableList<T extends List> {
    /* ... */
}
Copier après la connexion

Ceci est réalisé en utilisant l'extension mot-clé.

Équivalent en C

Contrairement à Java, C n'a pas d'équivalent direct au mot-clé extends pour contraindre les modèles. Cependant, il existe un moyen d'obtenir des contraintes similaires en utilisant le trait de type std::is_base_of en C 11 :

#include <type_traits>

template<typename T>
class observable_list {
    static_assert(std::is_base_of<list, T>::value, "T must inherit from list");
    // code here..
};
Copier après la connexion

Approches alternatives

Bien que cette approche fonctionne, il rompt avec les principes de conception typiques du C. Au lieu de cela, il peut être plus approprié d'utiliser des contraintes basées sur les traits :

#include <type_traits>

template<typename T>
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");
    // code here...
};

template<typename T>
struct has_const_iterator : std::false_type {};

template<typename T>
struct has_const_iterator<T, Void<typename T::const_iterator>> : std::true_type {};

struct has_begin_end_impl {
    template<typename T, typename Begin = decltype(std::declval<const T&>().begin()),
                         typename End   = decltype(std::declval<const T&>().end())>
    static std::true_type test(int);
    template<typename... Args>
    static std::false_type test(...);
};

template<typename T>
struct has_begin_end : decltype(has_begin_end_impl::test<T>(0)) {};

using Void = typename void_<>::type;

template<typename... Args>
struct void_ {
    using type = void;
};
Copier après la connexion

Cette approche définit des traits personnalisés pour vérifier des exigences spécifiques (par exemple, l'existence de fonctions const_iterator, start et end). Il offre plus de flexibilité et permet des messages d'erreur personnalisés.

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