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

C++ Discussion :

Que veut dire cette ligne ?


Sujet :

C++

  1. #1
    Membre éprouvé
    Profil pro
    Inscrit en
    Septembre 2009
    Messages
    1 821
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2009
    Messages : 1 821
    Points : 979
    Points
    979
    Par défaut Que veut dire cette ligne ?
    Bonjour,

    Je débute en C++ mais je connais bien le C.

    Que fait cette ligne exactement ?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    static foo::expose::json::NamespaceNode ns_config(&ns_port, "config");
    ce que j'ai compris, c'est que ça déclare en local dans le fichier .cxx : la fonction ns_config dans le spacename "foo::expose::json::NamespaceNode"
    ... ce que je ne comprends pas, c'est qu'il y a dans ce prototype des arguments, ça ne devrait pas être plutôt ça qu'il devrait y avoir ?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    static foo::expose::json::NamespaceNode ns_config(ns_port_t * ns_port, char * str);

    Merci d'avance

  2. #2
    Expert éminent
    Homme Profil pro
    Ingénieur développement matériel électronique
    Inscrit en
    Décembre 2015
    Messages
    1 565
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 61
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Ingénieur développement matériel électronique
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Décembre 2015
    Messages : 1 565
    Points : 7 648
    Points
    7 648
    Par défaut
    Bonjour,

    La ligne ne déclare pas une fonction mais définit une instance d'objet statique. Les deux paramètres sont des valeurs passées au constructeur de foo::expose::json::NamespaceNode.
    Et, tu as raison si c'était une déclaration de fonction, les paramètres seraient alors des types ou des paramètres typés.

    On aurait pu aussi l'écrire :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    static auto ns_config = foo::expose::json::NamespaceNode(&ns_port, "config");
    Qui est plus compréhensible quand on vient du C.

  3. #3
    Membre éprouvé
    Profil pro
    Inscrit en
    Septembre 2009
    Messages
    1 821
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2009
    Messages : 1 821
    Points : 979
    Points
    979
    Par défaut
    ok, merci pour l'info
    ... et effectivement la second écriture est beaucoup plus compréhensible, je ne vois pas trop l’intérêt de la première !

  4. #4
    Membre éprouvé
    Profil pro
    Inscrit en
    Septembre 2009
    Messages
    1 821
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2009
    Messages : 1 821
    Points : 979
    Points
    979
    Par défaut
    Bonjour,

    J'ai aussi une interrogation sur cette déclaration de structure, je ne comprends pas exactement ce que ça fait :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    struct Foo {
        typedef bla::expose::ParamList <
        bla::expose::ParamVal<bla_infos_t *>
        > P;
     
        //...
    };
    ... ça fait quoi exactement les opérateurs < et > ?


    Merci d'avance


    Pour infos, déclaration du template ParamList :
    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
    18
    19
    20
    21
    22
    23
    24
    25
    26
     
     
    namespace bla {
    namespace expose {
     
    	// ...
     
    	template <typename... T>
    	struct ParamList {
    		typedef int (*get_t)(typename T::get_ptr_type...);
    		typedef int (*set_t)(typename T::set_ptr_type...);
    		typedef int (*add_t)(typename T::set_ptr_type...);
    		typedef int (*def_t)(typename T::ptr_type...);
    		typedef typename details::DelPtrTypeCalc<T...>::type del_t;
    		typedef typename details::ItrPtrTypeCalc<T...>::type itr_t;
    		typedef int (*json_get_all_t)(const bla::expose::json::Request *req,
    										  bla::ostreamBuf *os);
     
    		typedef typename details::KeyTypeList<T...>::type key_list;
    		typedef typename details::ValTypeList<T...>::type val_list;
    		static constexpr size_t key_cnt = details::KeyTypeList<T...>::size;
    		static constexpr size_t val_cnt = details::ValTypeList<T...>::size;
    	};
     
    }  // namespace expose
    }  // namespace bla
    Pour information, j'ai quelques connaissances en langages orientés objets (java, vba, ...)

  5. #5
    Expert éminent
    Homme Profil pro
    Ingénieur développement matériel électronique
    Inscrit en
    Décembre 2015
    Messages
    1 565
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 61
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Ingénieur développement matériel électronique
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Décembre 2015
    Messages : 1 565
    Points : 7 648
    Points
    7 648
    Par défaut
    Citation Envoyé par boboss123 Voir le message
    ... ça fait quoi exactement les opérateurs < et > ?
    Le C++ n'est pas le C. Avant de passer il te faut peut-être apprendre le langage.
    < et > dans l'exemple que tu donnes ne sont pas des opérateurs, ils permettent ici de fournir des paramètres de template. La métaprogrammation est un des paradigmes fondamentaux du C++.

  6. #6
    Membre éprouvé
    Profil pro
    Inscrit en
    Septembre 2009
    Messages
    1 821
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2009
    Messages : 1 821
    Points : 979
    Points
    979
    Par défaut
    J'ai lu quelques tutos sur les templates mais je n'ai pas trouvé d'explication de ce qu'était les points de suspension dans "<typename... T>" (tous les exemples que j'ai vus n'en avaient pas).
    De plus, je n'ai pas trouvé d'explication sur la signification de "> P"

  7. #7
    Expert éminent sénior
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 614
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 614
    Points : 30 626
    Points
    30 626
    Par défaut
    Salut,

    Pour te permettre de comprendre, sans te donner un cours complet sur les template, on va essayer de t'en expliquer le principe

    Il faut -- avant tout -- comprendre que les template vont nous faire "basculer" dans un paradigme appelé le "paradigme générique".

    Ce paradigme nous permet -- essayons de faire aussi simple que possible -- de dire au compilateur quelque chose qui pourrait ressembler à
    Je ne sais pas encore quel est le type réel des données que je vais utiliser, mais je sais en revanche parfaitement bien comment je vais devoir les manipuler
    Car, tu l'auras compris, C++ est "très à cheval" sur les types de données que l'on manipule: si tu lui dit que tu vas travailler avec un type A, il faut que beaucoup de conditions soient remplies pour qu'il accepte que tu lui passe un type B à la place.

    Vu que tu viens du C, on pourrait faire un parallèle "très lointain" avec le type void * qui permet de prendre un pointeur sur "n'importe quel type" de donnée, mais sans avoir la possibilité avant d'avoir trouvé un moyen correct et efficace pour déterminer le type réel de la donnée.

    Avec la programmation générique, nous pouvons donc écrire des fonctions et des structures qui vont utiliser des données dont nous ne savons pas encore -- au moment d'écrire le code -- quel en sera le type. Par exemple, une fonction min ou pourrait s'écrire sous la forme de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    template <typename T>
    T min( T a, T b){
        if(a < b)
            return a;
    return b;
    }
    ou bien, nous pourrions créer une structure "coordonnée" qui contiennt les coordonnées sur les axes des X, des Y et des Z sous la forme de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    template <typename T>
    struct Coord{
        T x;
        T y;
        T z;
    };
    Les chevrons ne sont pas ici les opérateur "plus petit" et "plus grands" mais interviennent dans la syntaxe de langage pour nous permettre de fournir une "liste de paramètre templates" à la fonction ou à la structure. Autrement dit, pour nous permettre d'indiquer le nombre de types différents de données ainsi qu'un nom qui nous permettra de quel type on parle (car on pourrait très bien avoir trois types de données différents, sous une forme proche de template <typename A, typename B, typename C>)

    Dans le cas présent, le compilateur va donc se dire que la fonction ou la structure va utilise un type de donnée "dont on ignore tout" pour l'instant et que l'on identifie comme étant ... le type T.

    Seulement, tu le sais sans doute si tu viens du C, le type d'une donnée va -- non seulement --déterminer la manière dont cette donnée peut être manipulée (on ne peut pas manipuler de la même manière un int et un char[15]) mais aussi -- et surtout dans le cas présent -- l'espace mémoire nécessaire à la représentation complète de la donnée que le type nous permet de représenter (un int et un float vont demander un nombre de byte différent pour pouvoir être représenté en mémoire).

    Et, comme le compilateur ne sait pas quel est le type réel de donnée qui se cache derrière ce type générique identifié par T, ben, il est -- tout bonnement -- incapable de générer le code binaire exécutable qui sera adapté à ce type réel (merci lapalisse ).

    Et du coup, ben, si on veut pouvoir utiliser structure coord avec un type de donnée particulier (un int, un float, ou peut être même un double), il faudra que nous précisions explicitement quel est le type "réel" qui se cache derrière T.

    Cela nous donnera donc un code proche de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    Coord <int> maCoordInt; // x, y et z sont des données de type int
    Coord <float> maCoordFloat; // x, y et z sont des données de type float
    Coord <double> maCoordInt; // x, y et z sont des données de type double
    Encore une fois, < et > n'ont rien à voir avec les opérateur de comparaison "plus petit" ou "plus grand" : il sont un élément de la syntaxe qui permet au développeur d'indiquer le type de la donnée qui sera réellement utilisé, et dont on ignorait tout au moment de créer notre structure Coord.

    Et donc, quand tu trouve un code proche de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    struct Foo {
        typedef bla::expose::ParamList <
        bla::expose::ParamVal<bla_infos_t *>
        > P;
     
        //...
    };
    Hé bien, on va définir P comme étant un alias du type (c'est le but de typedef, n'est-ce pas ) bla::expose::ParamList "spécialisé" pour travailler avec des données qui seront de type bla::expose::ParamVal<bla_infos_t *>(qui est lui même le type bla::expose::ParamVal "spécialisé" pour travailler avec des données de type bla_infos_t *).

    Et si tu veux savoir à quoi correspond tout cela, ben il faudra arriver à "remonter le courant" pour savoir à quoi correspond bla_infos_t parce que c'est sans doute aussi l'alias d'un type "dont on ignore tout" qui est fourni par la liste des paramètres template.

    Et donc, pour conclure, le code
    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
    18
    19
    20
    21
    22
    23
    24
    namespace bla {
    namespace expose {
     
    	// ...
     
    	template <typename... T>
    	struct ParamList {
    		typedef int (*get_t)(typename T::get_ptr_type...);
    		typedef int (*set_t)(typename T::set_ptr_type...);
    		typedef int (*add_t)(typename T::set_ptr_type...);
    		typedef int (*def_t)(typename T::ptr_type...);
    		typedef typename details::DelPtrTypeCalc<T...>::type del_t;
    		typedef typename details::ItrPtrTypeCalc<T...>::type itr_t;
    		typedef int (*json_get_all_t)(const bla::expose::json::Request *req,
    										  bla::ostreamBuf *os);
     
    		typedef typename details::KeyTypeList<T...>::type key_list;
    		typedef typename details::ValTypeList<T...>::type val_list;
    		static constexpr size_t key_cnt = details::KeyTypeList<T...>::size;
    		static constexpr size_t val_cnt = details::ValTypeList<T...>::size;
    	};
     
    }  // namespace expose
    }  // namespace bla
    va déclarer une structure de de type ParamList pour qui utilisera "un nombre inconnu" de types de données "dont on ignore tout" (le code typename ... T) et qui déclarera en interne une série d'alias de type bien particuliers (c'est ce que l'on appelle une spécialisation totale), basée sur la liste de ces types dont "on ignore tout" et que l'on a identifié par T.

    Cette structure se trouve dans "une boite de rangement" (un "espace de noms") qui est appelée expose, et qui se trouve elle-même dans une boite de rangement (un "espace de noms" appelée bla.

    Si tu es "à l'extérieur" de la boîte de rangement nommé bla et que tu veux utiliser cette structure ParamList, il faudra donc que tu y accède en entrant dans la boite bla, puis dans la boite expose, et, bien sur, que tu n'oublie pas de fournir les types réels qui seront utilisés, par exemple
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    auto lesParam = bla::expose::ParamList<int, float double>; // lesParam manipule trois données, respectivement
                                                               // de type int, float et double,
                                                               // et expose en outre en interne une série d'alias de type et d'expression constantes pour chacun de ces trois paramètre
    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

  8. #8
    Membre expert
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2011
    Messages
    739
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hérault (Languedoc Roussillon)

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

    Informations forums :
    Inscription : Juin 2011
    Messages : 739
    Points : 3 627
    Points
    3 627
    Par défaut
    Plutôt que regarder des tutos sur tel ou tel partie, je pense qu'il est préférable de commencer par un cours C++ de A à Z. Les philosophies de C et C++ sont très différentes et la manière d'aborder les choses aussi. Le point primordial est d'oublier le C.

    Pour le cours, il en faut un qui commence au minimum par C++11 au risque de tomber sur des cours obsolètes.

  9. #9
    Membre actif Avatar de fmartini
    Homme Profil pro
    Ingénieur en Cybersécurité
    Inscrit en
    Mai 2013
    Messages
    59
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Suisse

    Informations professionnelles :
    Activité : Ingénieur en Cybersécurité
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Mai 2013
    Messages : 59
    Points : 296
    Points
    296
    Par défaut
    Citation Envoyé par boboss123 Voir le message
    J'ai lu quelques tutos sur les templates mais je n'ai pas trouvé d'explication de ce qu'était les points de suspension dans "<typename... T>" (tous les exemples que j'ai vus n'en avaient pas).
    De plus, je n'ai pas trouvé d'explication sur la signification de "> P"
    "..." est un argument variadique, il permet à une fonction d'accepter un nombre quelconque d'arguments supplémentaires.

    Concernant "> P". il suffit de lire le code en entier :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    typedef bla::expose::ParamList <
        bla::expose::ParamVal<bla_infos_t *>
        > P;
    C'est un Template dont le code est détaillé sur plusieurs ligne pour un soucis de visibilité.

  10. #10
    Membre éprouvé
    Profil pro
    Inscrit en
    Septembre 2009
    Messages
    1 821
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2009
    Messages : 1 821
    Points : 979
    Points
    979
    Par défaut
    Merci pour vos explications, je pense avoir tout compris
    ... et effectivement, il faudrait que je mette à lire intégralement un cours de C++

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

Discussions similaires

  1. Que veut dire cette ligne ?
    Par dsant dans le forum C
    Réponses: 4
    Dernier message: 26/04/2012, 16h23
  2. Que veut dire cette erreur ?
    Par Invité dans le forum jQuery
    Réponses: 3
    Dernier message: 04/04/2011, 09h51
  3. Que veut dire cette syntaxe: (key == 13) && ente && ente();
    Par geekforever dans le forum Général JavaScript
    Réponses: 2
    Dernier message: 25/10/2010, 21h32
  4. Que veut dire cette erreur (au runtime) ?
    Par corseb-delete dans le forum Général Java
    Réponses: 6
    Dernier message: 08/04/2008, 12h29

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