IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

SL & STL C++ Discussion :

std::allocator pour char et wchar_t


Sujet :

SL & STL C++

  1. #1
    Membre éprouvé
    Homme Profil pro
    Enseignant Chercheur
    Inscrit en
    Juillet 2009
    Messages
    122
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Enseignant Chercheur

    Informations forums :
    Inscription : Juillet 2009
    Messages : 122
    Par défaut std::allocator pour char et wchar_t
    Bonjour à tous,

    je lisais récemment l'article de Andreas et Masur sur les allocateurs et je suis allé voir l'implémentation de l'allocateur par défaut de la STL (gcc-g++-4.6.3.tar.gz pour être exact).

    Dans le fichier d'en-tête allocator.h, on y trouve bien tout ce qui est expliqué dans l'article (typedef, spécialisation pour le type void, ...). Jusque ici, tout va bien... Puis apparaissent les quelques lignes suivantes:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
      // Inhibit implicit instantiations for required instantiations,
      // which are defined via explicit instantiations elsewhere.
    #if _GLIBCXX_EXTERN_TEMPLATE
      extern template class allocator<char>;
      extern template class allocator<wchar_t>;
    #endif
    Les instanciations spécialisées pour les types char et wchar_t apparaissent dans le fichier allocator-inst.cc,

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    namespace std
    {
      template class allocator<char>;
      template class allocator<wchar_t>;
    } // namespace std
    La seule conséquence que je vois à ces spécialisations particulières est d'empêcher l'utilisateur de spécialiser lui-même les allocateurs pour char et pour wchar_t.

    1. Est-ce le cas ou bien n'ai-je rien compris?
    2. Y a-t-il d'autres conséquences/avantages à faire cela?
    3. Pourquoi ne faire cela que pour les type char et wchar_t et pas pour d'autres types de base (int, float, ...)?


    Mes questions sont peut-être naïves (désolé dans ce cas) mais j'aimerais bien comprendre ce qui motive ce choix pour les développeurs de la STL. Si certains peuvent éclairer ma lanterne, merci d'avance!

  2. #2
    Rédacteur/Modérateur
    Avatar de JolyLoic
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2004
    Messages
    5 463
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Août 2004
    Messages : 5 463
    Par défaut
    Instancier explicitement un template a pour effet d'instancier toutes ses fonctions membres, au lieu de ne les instancier qu'à la demande.

    J'imagine qu'ici le but est que ces fonctions soient définies une fois, dans une bibliothèque. Et non pas à chaque usage.
    Ma session aux Microsoft TechDays 2013 : Développer en natif avec C++11.
    Celle des Microsoft TechDays 2014 : Bonnes pratiques pour apprivoiser le C++11 avec Visual C++
    Et celle des Microsoft TechDays 2015 : Visual C++ 2015 : voyage à la découverte d'un nouveau monde
    Je donne des formations au C++ en entreprise, n'hésitez pas à me contacter.

  3. #3
    Membre éprouvé
    Profil pro
    Inscrit en
    Novembre 2004
    Messages
    2 766
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2004
    Messages : 2 766
    Par défaut
    Citation Envoyé par JolyLoic Voir le message
    Instancier explicitement un template a pour effet d'instancier toutes ses fonctions membres, au lieu de ne les instancier qu'à la demande.
    Tu pourrais détailler, STP ?

  4. #4
    Rédacteur/Modérateur
    Avatar de JolyLoic
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2004
    Messages
    5 463
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Août 2004
    Messages : 5 463
    Par défaut
    Aux erreurs de syntaxe près (je n'utilise pas souvent ça) :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
     
    template<class T>
    class MaClasse
    {
      void g(T t) {t.f();}
    };
     
    int main()
    {
      MaClass<int> a; // Pas d'erreur, la fonction g n'a pas encore été instanciée
      a.g(3); // Erreur, on tente d'instancier g, qui demande que T possède 
                // une fonction membre nommée f
    }
     
    template class MaClasse<double>; // Erreur, car là on instancie l'ensemble de 
                // la classe MaClasse avec le type double, y compris la fonction g 
                // qui pose le même problème que tout à l'heure
    Ma session aux Microsoft TechDays 2013 : Développer en natif avec C++11.
    Celle des Microsoft TechDays 2014 : Bonnes pratiques pour apprivoiser le C++11 avec Visual C++
    Et celle des Microsoft TechDays 2015 : Visual C++ 2015 : voyage à la découverte d'un nouveau monde
    Je donne des formations au C++ en entreprise, n'hésitez pas à me contacter.

  5. #5
    Membre éprouvé
    Homme Profil pro
    Enseignant Chercheur
    Inscrit en
    Juillet 2009
    Messages
    122
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Enseignant Chercheur

    Informations forums :
    Inscription : Juillet 2009
    Messages : 122
    Par défaut
    Merci JolyLoic pour ces réponses et cet exemple. Je crois comprendre un peu mieux maintenant: il ne s'agit pas particulièrement d'empêcher la spécialisation pour char et wchar_t mais plutôt d'assurer à la bibliothèque qu'elle dispose, au moins, d'un allocateur fonctionnel pour ces deux types. Cela répond à mes deux premières interrogations.

    Pour la troisième, pourquoi se limiter uniquement à ces deux types? Peut être pour assurer le bon fonctionnement de std::string? Une autre idée me vient en tête, le type char étant le plus petit, assurer la capacité à allouer des char peut impliquer l'assurance de pouvoir allouer n'importe quoi de plus gros, via le rebind de l'allocateur... Est-ce une raison?

  6. #6
    Expert éminent
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 633
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 633
    Par défaut
    Salut,

    Pour répondre à ta troisième question.

    Je vois différentes raisons au fait que l'instanciation explicite soit faite pour les char et wchar:

    D'abord, ce sont ces types primitifs qui sont utilisés comme type de base pour les chaines de caractères, pas les int, ni les float, ni quoi que ce soit d'autre: ce sont les char et éventuellement les char16_t /char32_t

    Ensuite, une bonne majorité des conversions (et surtout celles qui ont recours à stringstream) se feront vers/ au départ des chaines de caractères.

    En outre, la norme précise que la taille de n'importe quel type de donnée est calculée sur la base du caractère. En fournissant un allocateur spécifique pour le caractère, on a donc de toutes manière la certitude de pouvoir disposer d'un allocateur susceptible de travailler avec n'importe quel type.

    Enfin, il faut savoir que le recours à l'instanciation explicite a tendance à augmenter la quantité de code binaire généré de manière assez significative.

    Il peut "simplement" avoir semblé inutile aux développeurs de ta version de la STL de forcer la génération de code binaire pour l'allocateur des autres types primitifs alors que celui explicitement instancié pour le char (et le wchar_t) est "amplement suffisant" pour fonctionner avec tous les autres types
    A méditer: La solution la plus simple est toujours la moins compliquée
    Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 février 2014
    mon tout nouveau blog

  7. #7
    Membre éprouvé
    Homme Profil pro
    Enseignant Chercheur
    Inscrit en
    Juillet 2009
    Messages
    122
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Enseignant Chercheur

    Informations forums :
    Inscription : Juillet 2009
    Messages : 122
    Par défaut
    Merci pour vos réponses, cela clarifie pas mal de choses sur ces instanciations

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Convertion std::wstring en char*
    Par pegase06 dans le forum SL & STL
    Réponses: 48
    Dernier message: 05/03/2008, 15h43
  2. allocation de memoire pour char**
    Par Guillaume602 dans le forum C++
    Réponses: 3
    Dernier message: 03/04/2006, 20h01
  3. (Problème avec...) conversion de std::string en char
    Par crossbowman dans le forum SL & STL
    Réponses: 7
    Dernier message: 05/03/2006, 19h54
  4. Réponses: 21
    Dernier message: 20/02/2006, 11h00
  5. Conversion char * vers wchar_t
    Par Zapan dans le forum C++
    Réponses: 4
    Dernier message: 24/02/2005, 15h56

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo