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++

  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)

  9. #9
    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
    Ok alors je suis un peu perdu sur les details dans ce cas. Peut etre que je melange avec les parametres par defaut d'arguments de fonction plutot.

  10. #10
    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
    @Klaim: Non, pareil pour les arguments pas défaut des fonctions, une seule et unique fois. En faite il y a une nuance si tu changes de scope entre deux déclarations de la même fonction, mais c'est franchement tordue comme utilisation.

    Par contre tu peux définir plusieurs arguments par défaut entre différentes déclarations, tant que c'est pas pour les mêmes paramètres. Dans ce cas ils se cumulent.

  11. #11
    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
    En gros, vous êtes en train de me dire que si un .h définit une fonction, et que 10 fichiers font une déclaration de cette fonction, n'importe laquelle peut se charger de définir les valeurs par défaut pour cette fonction ?

  12. #12
    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
    On est en train de te dire que ca peut devenir vicieux oui

  13. #13
    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
    Oui on peut avoir des choses très spécial en le voulant. Mais au final retenir : argument par défaut lors de la première déclaration, donc dans le fichier de déclarations anticipées si tu en fais un, c'est encore le plus simple.

  14. #14
    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
    Bon, he bien je me résous à ce qui m'apparaît comme un défaut du C++.

  15. #15
    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 ça serait un défaut ? Tu trouves pas que ce serait justement contraignant de devoir les réécrire à chaque fois ? Au risque de se tromper ?

    Il y a plein de règles du C++ qui permettent de faire des choses étranges, mais l'idée de base derrière est souvent simple et dans l'esprit du principe de moindre surprise.

  16. #16
    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
    Ben on est obligé de faire une recherche de déclarations dans tout le projet pour savoir s'il existe d'éventuelles valeurs par défaut. Je ne trouve pas ça terrible...

  17. #17
    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
    Oui, sauf que si c'est bien fait, c'est dans la déclaration anticipée, c'est facile à localiser. Il est vrai qu'on peut avoir plusieurs déclarations, mais en général ça se limite à 2 ou 3, pas à 50. Et d'un autre côté c'est le boulot d'un IdE de faire ça (ie t'informer des prototypes).

    Et imagines l'inverse, tu veux rajouter des paramètres par défaut, t'es obligé de le faire dans toutes les déclarations, là c'est contraignant ... (même si l'IdE peut t'aider à le faire).

  18. #18
    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
    Pour les classes, il ne faudrait le faire qu'à la définition.

  19. #19
    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
    D'accord, mais dans ce cas là comment tu fais pour utiliser ton template là où tu n'as besoin que d'une déclaration ? Tu inclus la définition ? Tu payes du temps de compilation supplémentaire pour rien.

    Il ne faut pas oublier qu'une déclaration anticipée, ça reste une déclaration. On retrouve la même dualité que celle de déclaration / définition pour les fonctions non template. Et dans ce cas c'est bien la déclaration que tu regardes et non la définition : alors pourquoi quand tu veux voir comment instancier un template tu regarderais la définition et non la déclaration ?

    Je suis d'accord que n'avoir les arguments par défaut qu'à un endroit est une contrainte, mais je ne vois pas de solution moins contraignantes.

+ 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