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

Langage C++ Discussion :

Paramètres template par défaut


Sujet :

Langage C++

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    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 Paramètres template par défaut
    Bonjour,

    Je suis en train de mettre le nez dans le code de Boost::Interprocess, et suis tombé sur cette classe :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    template<class MutexFamily, class VoidPointer, std::size_t MemAlignment>
    class rbtree_best_fit
    {
        ...
    };
    Jusque là, rien de particulier.

    Dans un autre fichier, je tombe sur la déclaration anticipée suivante :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    template<class MutexFamily, class VoidMutex = offset_ptr<void>, std::size_t MemAlignment = 0>
    class rbtree_best_fit;
    Comment se fait-il que soient apparus des valeurs par défaut non présente dans la définition de classe template originale ?

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

    Informations professionnelles :
    Activité : aucun

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

    Il faut savoir que la déclaration anticipée d'une classe template va avoir plusieurs objectif:

    D'abord, comme toute déclaration anticipée, celui de faire savoir au compilateur que la classe existe, avec les paramètres template indiqués.

    Ensuite, Les paramètres template suivent le même principe que les paramètres "classiques" au niveau des valeurs par défaut, à savoir que si tu déclares anticipativement une classe sous la forme de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    template<class MutexFamily, class VoidMutex = offset_ptr<void>, std::size_t MemAlignment = 0>
    class rbtree_best_fit;
    le compilateur acceptera toute tentative de définition d'un objet de type rbtree_best_fit avec un, deux ou trois paramètres template.

    Les "paramètres manquants" représenteront les types (ou valeur pour MemAlignment) représenté par les valeur par défaut.

    Ansi, tu peux parfaitement déclarer des objets proches de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    rbtree_best_fit<MonMutex>  tree;// équivalent à rbtree_best_fit<MonMutex,offset_ptr<void>, 0>
    rbtree_best_fit<MonMutex, MonOffset>  tree; // équivalent à rbtree_best_fit<MonMutex, MonOffset, 0>
    Seulement, la déclaration anticipée intervient dans le choix du "best match".

    Autrement dit, si, pour une raison ou une autre, il n'existe pas de spécialisation partielle qui correspond d'avantage au type de données que tu vas déclarer, le compilateur va choisir la déclaration anticipée.

    Seulement, la déclaration anticipée correspond alors à une classe vide, ce qui fait que dés que tu essayeras d'utiliser la moindre fonction (un constructeur ou n'importe quelle fonction définie dans les spécialisations partielles), tu risque de te retrouver avec une erreur de compilation t'indiquant que la dite fonction n'existe pas.

    Ceci dit, il n'est pas du tout impossible, étant donné les problèmes que peuvent provoquer les références croisées, comme l'utilisation de fonctions propres à offset_ptr<void>, au niveau des fonctions inline que tu puisse trouver une spécialisation partielle proche de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    template typename <class MutexFamily>
    class rbtree_best_fit<MutexFamily, offset_ptr<void>, 0>{
       /* potentiellement pas mal de choses  */
    };
    dans un fichier *.tpp ou similaire.(je te rappelle que toutes les fonctions d'une classe template doivent a priori etre inline )

    Ce fichier *.tpp sera alors sans doute inclus directement au niveau des fichiers d'implémentation qui ont recours au rbtree_best_fit et précédé du fichier dans lequel la classe offset_ptr est déclarée
    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

  3. #3
    Membre Expert

    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Août 2004
    Messages
    1 391
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France, Doubs (Franche Comté)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Août 2004
    Messages : 1 391
    Par défaut
    Le fichier de déclaration anticipé est inclus par le fichier de la définition. Les paramètres par défaut se cumulent sur l'ensemble des déclarations (et définition) présentes dans l'unité de compilation. Donc les paramètres par défaut sont bien toujours présents.

  4. #4
    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
    Je comprend bien ce que tu expliques, et je penses que je le savais déjà.
    Ce que je ne comprend pas, c'est pourquoi la déclaration anticipée a certains de ses paramètres par défaut, et pas la définition de la classe.
    Ou alors, je n'ai en fait pas compris ta réponse.

    Citation Envoyé par koala01 Voir le message
    je te rappelle que toutes les fonctions d'une classe template doivent a priori etre inline
    Pourquoi cela ?

  5. #5
    Membre Expert

    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Août 2004
    Messages
    1 391
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France, Doubs (Franche Comté)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Août 2004
    Messages : 1 391
    Par défaut
    Pourquoi tu voudrais écrire deux fois les paramètres template par défauts ? A part risquer d'écrire deux listes différentes et donc produire un code invalide (*), ça n'apporte pas grand chose (qui ne puisse être apporté par ton EDI). Là les paramètres n'y sont qu'une fois, pas d'erreur possible.

    (*) Mais même identique c'est invalide, cf message suivant.

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

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 644
    Par défaut
    Citation Envoyé par oodini Voir le message
    Pourquoi cela ?
    Parce qu'il faut que le code d'implémentation de la fonction soit disponible au moment de la compilation.

    Du coup, à chaque fois que le compilateur rencontre une déclaration de variable pour laquelle les paramètres template sont fournis, il produira le code binaire correspondant.

    Mais, à coté de cela, il y a le principe de la définition unique: il ne peut donc exister qu'une seul version du code binaire pour une fonction donnée, et donc une seule version du code binaire de la fonction spécialisée pour un type donné.

    La seule exception à cette règle concerne les fonctions inline, pour lesquelles le code binaire correspondant peut exister en plusieurs versions.

    Pour arriver à concilier ces deux points de vue, la seule solution passe par des fonctions inlines
    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 Expert
    Avatar de Klaim
    Homme Profil pro
    Développeur de jeux vidéo
    Inscrit en
    Août 2004
    Messages
    1 717
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur de jeux vidéo
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Août 2004
    Messages : 1 717
    Par défaut
    En fait, le truc qui est troublant c'est que C++ permet bien de definir les valeurs par defaut dans la declaration, et ce meme si il y a plusieurs declarations differentes avec des paramettres par defaut different.

    Recemment sur son blog Herb Sutter a rappele que c'est une tres mauvaise idee d'utiliser des paramettre par defauts dans plus d'une declaration, et que c'est bien mieu si on peut completement eviter les paramettres par defaut.

  8. #8
    Membre Expert

    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Août 2004
    Messages
    1 391
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France, Doubs (Franche Comté)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Août 2004
    Messages : 1 391
    Par défaut
    @koala01: Il y a plus d'une exception :
    There can be more than one definition of [...] inline function [...] member function of a class template (14.5.1.1) [...] in a program provided that each definition appears in a different translation unit [...]
    Il peut y avoir plus d'une définition [...] des fonctions inline [...] des fonctions membre d'une classe template [...] dans un programme pour peu que chaque définition soit dans une unité de compilation différente [...]
    Donc le caractère inline n'est pas nécessaire (dans notre cas) en réalité.

    @Klaim: Je suis pas certain d'avoir compris ton message, les paramètres par défaut pour un paramètre ne doivent pas être différents entre deux déclaration (définition), ni même identiques. Ceci est illégal :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    template<class =int> struct A;
    template<class =int> struct A {};
    (la règle exact fait intervenir la notion de scope en plus)

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

Discussions similaires

  1. [PHP 5.2] Fonction file_get_contents et paramètre maxlen par défaut
    Par Bisûnûrs dans le forum Langage
    Réponses: 6
    Dernier message: 17/08/2009, 12h33
  2. [Typo3] Emplacement des templates par défaut
    Par gleyral dans le forum EDI, CMS, Outils, Scripts et API
    Réponses: 2
    Dernier message: 31/01/2009, 12h22
  3. [XI] Paramètre date par défaut
    Par leloup84 dans le forum SAP Crystal Reports
    Réponses: 0
    Dernier message: 02/10/2007, 16h00
  4. [Joomla!] Impossible de modifier le template par défaut
    Par MarcS dans le forum EDI, CMS, Outils, Scripts et API
    Réponses: 8
    Dernier message: 28/03/2007, 16h57
  5. Réponses: 15
    Dernier message: 21/08/2006, 01h41

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