Maison >développement back-end >C++ >Comment les compteurs de temps de compilation peuvent-ils être implémentés en C à l'aide de la fonctionnalité de recherche de fonction et de portée d'espace de noms ?

Comment les compteurs de temps de compilation peuvent-ils être implémentés en C à l'aide de la fonctionnalité de recherche de fonction et de portée d'espace de noms ?

Mary-Kate Olsen
Mary-Kate Olsenoriginal
2024-12-20 16:25:10502parcourir

How Can Compile-Time Counters Be Implemented in C   Using Function Lookup and Namespace-Scope Functionality?

C prend-il en charge les compteurs de temps de compilation ?

Dévoilement de la nuance dans la métaprogrammation au moment de la compilation

Dans le domaine de l'introspection, il est nécessaire de attribuez dynamiquement des identifiants uniques ou exécutez des opérations similaires sur les types au moment de la compilation. Bien que la métaprogrammation de modèles soit essentiellement un langage fonctionnel, il semble manquer des variables globales et de l'état modifiable nécessaires pour implémenter ces opérations.

Étonnamment, la réponse à ce dilemme réside à l'intersection de la recherche de fonctions et des fonctionnalités de portée d'espace de noms. . La recherche de fonctions offre un moyen d'extraire l'état numérique d'un ensemble défini de fonctions déclarées.

Dans l'exemple suivant, nous montrons comment cette technique peut être appliquée pour réaliser un comptage au moment de la compilation :

template< size_t n > // This type returns a number through function lookup.
struct cn // The function returns cn<n>.
    { char data[ n + 1 ]; }; // The caller uses (sizeof fn() - 1).

template< typename id, size_t n, size_t acc >
cn< acc > seen( id, cn< n >, cn< acc > ); // Default fallback case.

/* Evaluate the counter by finding the last defined overload.
   Each function, when defined, alters the lookup sequence for lower-order
   functions. */
#define counter_read( id ) \
( sizeof seen( id(), cn< 1 >(), cn< \
( sizeof seen( id(), cn< 2 >(), cn< \
( sizeof seen( id(), cn< 4 >(), cn< \
( sizeof seen( id(), cn< 8 >(), cn< \
( sizeof seen( id(), cn< 16 >(), cn< \
( sizeof seen( id(), cn< 32 >(), cn< 0 \
/* Add more as desired; trimmed for Stack Overflow code block. */ \
                      >() ).data - 1 ) \
                      >() ).data - 1 ) \
                      >() ).data - 1 ) \
                      >() ).data - 1 ) \
                      >() ).data - 1 ) \
                      >() ).data - 1 )
#define counter_inc( id ) \
cn< counter_read( id ) + 1 > \
seen( id, cn< ( counter_read( id ) + 1 ) &amp; ~ counter_read( id ) >, \
          cn< ( counter_read( id ) + 1 ) &amp; counter_read( id ) > )

Cette approche permet l'attribution d'identifiants uniques et la création de structures de données avec des tailles déterminées au moment de la compilation. Il convient de noter que cette technique peut également être implémentée à l'aide du mot-clé constexpr de C 11, comme indiqué dans le code mis à jour ci-dessous :

#define COUNTER_READ_CRUMB( TAG, RANK, ACC ) counter_crumb( TAG(), constant_index< RANK >(), constant_index< ACC >() )
#define COUNTER_READ( TAG ) COUNTER_READ_CRUMB( TAG, 1, COUNTER_READ_CRUMB( TAG, 2, COUNTER_READ_CRUMB( TAG, 4, COUNTER_READ_CRUMB( TAG, 8, \
    COUNTER_READ_CRUMB( TAG, 16, COUNTER_READ_CRUMB( TAG, 32, COUNTER_READ_CRUMB( TAG, 64, COUNTER_READ_CRUMB( TAG, 128, 0 ) ) ) ) ) ) ) )

#define COUNTER_INC( TAG ) \
constexpr \
constant_index< COUNTER_READ( TAG ) + 1 > \
counter_crumb( TAG, constant_index< ( COUNTER_READ( TAG ) + 1 ) &amp; ~ COUNTER_READ( TAG ) >, \
                                                constant_index< ( COUNTER_READ( TAG ) + 1 ) &amp; COUNTER_READ( TAG ) > ) { return {}; }

En résumé, bien que la métaprogrammation de modèles traditionnelle manque d'effets secondaires, il est possible d'obtenir un espace de noms -Fonctionnalité de compteur de portée en tirant parti de la recherche de fonctions et des techniques susmentionnées. Ces méthodes fournissent une solution pratique pour attribuer dynamiquement des identifiants uniques et déterminer la taille des structures de données au moment de la compilation, améliorant ainsi les capacités d'introspection des applications C.

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