Maison >développement back-end >C++ >Comment CRTP en C peut-il gérer les typedefs à partir de classes dérivées pour le polymorphisme statique ?

Comment CRTP en C peut-il gérer les typedefs à partir de classes dérivées pour le polymorphisme statique ?

DDD
DDDoriginal
2024-12-10 09:42:18949parcourir

How Can CRTP in C   Handle Typedefs from Derived Classes for Static Polymorphism?

Polymorphisme statique C (CRTP) avec typesdefs à partir de classes dérivées

Dans le polymorphisme statique, également connu sous le nom de polymorphisme au moment de la compilation, les types de les classes dérivées sont connues de la classe de base au moment de la compilation. Ceci peut être réalisé en utilisant le modèle de modèle curieusement récurrent (CRTP). Cependant, vous souhaiterez peut-être personnaliser les types de retour des fonctions en fonction du type dérivé.

Considérez le code suivant :

template <typename derived_t>
class base {
public:
    typedef typename derived_t::value_type value_type;
    value_type foo() {
        return static_cast<derived_t*>(this)->foo();
    }
};

template <typename T>
class derived : public base<derived<T>> {
public:
    typedef T value_type;
    value_type foo() {
        return T(); //return some T object (assumes T is default constructable)
    }
};

Cependant, ce code peut ne pas être compilé en raison de l'utilisation de l'alias de type value_type de la classe dérivée dans le modèle de classe de base. L'erreur est que la dérivée est incomplète lorsqu'elle est utilisée comme argument de modèle pour la base.

Une solution consiste à utiliser un modèle de classe de traits. Voici un exemple modifié :

// Declare a base_traits traits class template:
template <typename derived_t> 
struct base_traits;

// Define the base class that uses the traits:
template <typename derived_t> 
struct base { 
    typedef typename base_traits<derived_t>::value_type value_type;
    value_type base_foo() {
        return base_traits<derived_t>::call_foo(static_cast<derived_t*>(this));
    }
};

// Define the derived class; it can use the traits too:
template <typename T>
struct derived : base<derived<T>> { 
    typedef typename base_traits<derived>::value_type value_type;

    value_type derived_foo() { 
        return value_type(); 
    }
};

// Declare and define a base_traits specialization for derived:
template <typename T> 
struct base_traits<derived<T>> {
    typedef T value_type;

    static value_type call_foo(derived<T>* x) { 
        return x->derived_foo(); 
    }
};

En spécialisant base_traits pour chaque type dérivé, vous pouvez fournir les membres nécessaires (value_type et call_foo) requis par le modèle de classe de base. Cela vous permet d'accéder aux typedefs et aux fonctions de la classe dérivée dans le modèle de classe de base, obtenant ainsi un polymorphisme statique avec des types de retour 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!

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