Maison  >  Article  >  développement back-end  >  Comment initialiser des membres statiques dans des fonctions de modèle imbriquées en C ?

Comment initialiser des membres statiques dans des fonctions de modèle imbriquées en C ?

Barbara Streisand
Barbara Streisandoriginal
2024-11-01 16:47:02801parcourir

 How to Initialize Static Members in Nested Template Functions in C  ?

Initialisation des membres statiques C dans les fonctions de modèle imbriquées

L'initialisation des membres statiques peut être réalisée via des structures d'assistance imbriquées, en particulier dans les classes sans modèle. Cependant, cette approche peut rencontrer des problèmes lorsque la classe englobante est paramétrée par un modèle. Plus précisément, si l'objet d'assistance n'est pas accessible dans le code principal, la classe d'initialisation imbriquée peut ne pas être instanciée.

Considérez l'exemple simplifié suivant, qui illustre l'initialisation d'un vecteur :

<code class="cpp">struct A {
    struct InitHelper {
        InitHelper() { A::mA = "Hello, I'm A."; }
    };
    static std::string mA;
    static InitHelper mInit;

    static const std::string& getA(){ return mA; }
};
std::string A::mA;
A::InitHelper A::mInit;


template<class T>
struct B {
    struct InitHelper {
        InitHelper() { B<T>::mB = "Hello, I'm B."; }
    };
    static std::string mB;
    static InitHelper mInit;

    static const std::string& getB() { return mB; }
    static InitHelper& getHelper(){ return mInit; }
};
template<class T>
std::string B<T>::mB;
template<class T>
typename B<T>::InitHelper B<T>::mInit;</code>

Lors de la compilation avec g 4.4.1, plusieurs observations sont faites :

  • Avec [1] et [2] commentés, A = Bonjour, je suis A. Ceci signifie que l'initialisation fonctionne comme prévu.
  • Avec [1] non commenté, A = Bonjour, je m'appelle A. B = Cela démontre que l'initialisation de B::mB n'est pas déclenchée automatiquement.
  • Avec [1] et [2] non commentés, A = Bonjour, je suis A. B = Bonjour, je suis B. Cela confirme que l'accès à B : :mInit (via [2]) déclenche l'initialisation de B::mB.
  • Avec [1] commenté et [2] non commenté, un segfault se produit, indiquant qu'en accédant directement au helper lui-même, l'initialisation de B::mB est tentée prématurément, ce qui entraîne une erreur.

Ce comportement découle de l'interprétation par le compilateur de la norme ISO/IEC C 2003 (14.7.1). La norme stipule que :

"À moins qu'un membre d'un modèle de classe ou d'un modèle de membre ait été explicitement instancié ou explicitement spécialisé, la spécialisation du membre est implicitement instanciée lorsque la spécialisation est référencée dans un contexte qui nécessite que la définition de membre existe ; en particulier, l'initialisation (et tous les effets secondaires associés) d'une donnée membre statique ne se produit que si la donnée membre statique est elle-même utilisée d'une manière qui nécessite la définition de la donnée membre statique. exister."

Cela explique pourquoi, dans l'exemple donné, les membres statiques ne sont pas initialisés tant qu'ils ne sont pas accessibles via les méthodes getB() ou getHelper(). Instancier explicitement le modèle de classe ou le modèle de membre dans la fonction principale forcerait leur initialisation à ce stade. Cependant, pour les scénarios dans lesquels l'accès direct n'est pas réalisable, la norme ne spécifie pas de solution de contournement élégante pour initialiser les membres statiques dans les fonctions de modèle imbriquées.

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