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 :

[C++ 0x] decltype


Sujet :

Langage C++

  1. #1
    Rédacteur
    Avatar de 3DArchi
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    7 634
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 7 634
    Par défaut [C++ 0x] decltype
    Bonjour,
    J'ai regardé un peu la norme sur decltype et commencé à jouer un peu avec sur Visual Express 2010 qui supporte cette évolution.
    Or en lisant la norme, il y a des choses qui m'échappent.
    Pour rappel, voici ce que dit la norme (en rouge, c'est moi qui rajoute) :
    Citation Envoyé par draft 3090 ¤7.1.6.2 Simple type specifiers

    4 The type denoted by decltype(e) is defined as follows:
    [1]— if e is an unparenthesized id-expression or a class member access (5.2.5), decltype(e) is the type of the entity named by e. If there is no such entity, or if e names a set of overloaded functions, the program is ill-formed;
    [2]— otherwise, if e is a function call (5.2.2) or an invocation of an overloaded operator (parentheses arounde are ignored), decltype(e) is the return type of the statically chosen function;
    [3]— otherwise, if e is an lvalue, decltype(e) is T&, where T is the type of e;
    [4]— otherwise, decltype(e) is the type of e.
    The operand of the decltype specifier is an unevaluated operand (Clause 5).
    [ Example:
    const int&& foo();
    int i;
    struct A { double x; };
    const A* a = new A();
    decltype(foo()) x1 = i; // type is const int&& [5]
    decltype(i) x2; // type is int
    decltype(a->x) x3; // type is double
    decltype((a->x)) x4 = x3; // type is const double& [6]
    —end example ]
    Voilà ce que je comprend :
    [1] cas où on se base sur un identifiant, çad, dans le cas courant une variable (membre ou non). Rien à dire, c'est assez compréhensible ;
    [2] cas où on se base sur le retour d'une fonction (fonction, fonction membre, opérateur). Rien à dire, c'est assez compréhensible ;
    [3] est-ce mon anglais qui est mauvais, une subtilité dans 'sinon, si e est une lvalue' qui m'échappe ou manque-t-il le double parenthésage qui permet d'avoir une référence : if e is an lvalue, decltype((e)) is T& ?
    [4] quel cas cela concerne qui ne soit pas couvert par les précédents ? Une expression par exemple (decltype(T()+U()) ) ?
    [5] Ça ne compile pas avec visual 2010. Connaissant mal les rvalue reference, je ne sais pas dire s'il s'agit d'une erreur de visual ou d'une erreur de l'exemple de la spec : cannot convert from 'int' to 'const int &&'
    [6] J'ai du relire plusieurs fois le code et la norme avant de m'apercevoir que x4 est const double & car a est const. En gros, l'idée est de démontrer la différence entre l'exemple juste au dessus qui prend le type de la variable membre et celui-ci qui prend le type de l'expression. Le commentaire aurait pu être un pouillème plus clair.

    Merci.

  2. #2
    Membre Expert
    Avatar de Goten
    Profil pro
    Inscrit en
    Juillet 2008
    Messages
    1 580
    Détails du profil
    Informations personnelles :
    Âge : 34
    Localisation : France

    Informations forums :
    Inscription : Juillet 2008
    Messages : 1 580
    Par défaut
    [5] En effet c'est pas sensé compilé. C'est les derniers changement ça, je croyais que visual était pas à jour sur ce point là.
    Tu peux pas binder une lvalue a une rvalue (const ou non).

    Je sais pas si c'est voulu ou pas, mais il me semblait que quand ça compile pas c'est signalé. Si quelqu'un de plus habitué avec les us et coutumes de la norme qu'il fasse signe.

    Pour le reste j'ai pas le temps j'y reviendrais mais en effet y'a quelque trucs qui m'interpellent.

  3. #3
    Rédacteur
    Avatar de 3DArchi
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    7 634
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 7 634
    Par défaut
    En fouillant dans std.comp.c++, j'ai trouvé une question sur decltype ouverte par Scott Meyer et dans laquelle loufoque soulignait que le noeud est effectivement non pas dans le double parenthésage mais bien dans lvalue. Ce qui permet d'étendre le cas 3.
    Ceci dit, ça promet d'être une fonctionnalité très troublante :
    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
    struct TYPE {};
    int main()
    {
       TYPE t;
       TYPE *pt = &t;
     
       decltype(t) d1; // Cas [1] : TYPE
       decltype((t)) d2=t; // Cas [3] : TYPE &
     
       decltype (pt) d3=pt; // Cas [1] :TYPE*
       decltype (*pt) d4 = t; // Cas [3] :TYPE &
       decltype (&t) d5=pt; // Cas [4] :TYPE*
       decltype (++pt) d6 = pt; // Cas [3] :TYPE* &
       decltype (pt++) d7 = 0; // Cas [???] : Visual me dit TYPE *
     
       return 0;
    }

  4. #4
    Membre Expert
    Avatar de Joel F
    Homme Profil pro
    Chercheur en informatique
    Inscrit en
    Septembre 2002
    Messages
    918
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Chercheur en informatique
    Secteur : Service public

    Informations forums :
    Inscription : Septembre 2002
    Messages : 918
    Par défaut
    oui. Eric Niebler s'en arrache les cheveux au vu des differences de comportements entre decltype, boost::result_of et tr1::result_of ...

  5. #5
    Membre chevronné Avatar de Lavock
    Profil pro
    Inscrit en
    Octobre 2009
    Messages
    560
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2009
    Messages : 560
    Par défaut
    Citation Envoyé par Goten Voir le message
    [5] En effet c'est pas sensé compilé. C'est les derniers changement ça, je croyais que visual était pas à jour sur ce point là.
    Tu peux pas binder une lvalue a une rvalue (const ou non).

    Je sais pas si c'est voulu ou pas, mais il me semblait que quand ça compile pas c'est signalé. Si quelqu'un de plus habitué avec les us et coutumes de la norme qu'il fasse signe.
    D'après ce qui était passé sur comp.std.c++, feature viré depuis N3090... Si je me plante pas, les compilateurs se vautré sur ce cas, et personne a pu relevé son utilité...

    Pour d7, j'aurais dit cas 4. Après tout, c'est un rvalue.

  6. #6
    Membre Expert
    Avatar de Goten
    Profil pro
    Inscrit en
    Juillet 2008
    Messages
    1 580
    Détails du profil
    Informations personnelles :
    Âge : 34
    Localisation : France

    Informations forums :
    Inscription : Juillet 2008
    Messages : 1 580
    Par défaut
    D'après ce qui était passé sur comp.std.c++, feature viré depuis N3090... Si je me plante pas, les compilateurs se vautré sur ce cas, et personne a pu relevé son utilité...
    Quelle feature à été viré? ça :
    Tu peux pas binder une lvalue a une rvalue (const ou non).
    Car elle existait pas au début, puis elle a été rajouté, et donc elle aurait été encore enlevé?

  7. #7
    Membre chevronné Avatar de Lavock
    Profil pro
    Inscrit en
    Octobre 2009
    Messages
    560
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2009
    Messages : 560
    Par défaut
    Je suis en periode exam/projet donc j'ai pas tout lu, mais c'est passé en coup de vent sur mes mail il y a quelque jours :
    sujet comp.std.c++

    PS: Je suis trop jeune, pour moi cette feature à toujours exister ...

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

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