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 :

operator [] sur liste d'initialisation


Sujet :

C++

  1. #1
    Membre confirmé
    Homme Profil pro
    Développeur du dimanche
    Inscrit en
    Février 2013
    Messages
    154
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur du dimanche

    Informations forums :
    Inscription : Février 2013
    Messages : 154
    Par défaut operator [] sur liste d'initialisation
    Bonjour,

    J'aimerais remplacer le code suivant :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    std::vector<unsigned> vector = {5,6,7,8};
    unsigned a = vector[3]; // a = 8
    Par celui là :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    unsigned a = {5,6,7,8}[3]; // a = 8
    Mais mon compilateur me fait des embrouilles (Excess elements in scalar initializer). Est ce un problème de syntaxe ou est ce que le C++ n'admet tout simplement pas cette possibilité ?

    Merci pour vos réponses

  2. #2
    Membre émérite
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Juin 2014
    Messages
    345
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Finance

    Informations forums :
    Inscription : Juin 2014
    Messages : 345
    Par défaut
    Le compilateur n'a aucune idée de ce qu'est {5, 6, 7, 8}. Il faut le préciser :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    unsigned a = (std::vector<unsigned> {5, 6, 7, 8})[3];

  3. #3
    Membre confirmé
    Homme Profil pro
    Développeur du dimanche
    Inscrit en
    Février 2013
    Messages
    154
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur du dimanche

    Informations forums :
    Inscription : Février 2013
    Messages : 154
    Par défaut
    Moui.. M'enfin moi jvoulais éviter d'avoir à créer un vector en fait

  4. #4
    Membre Expert
    Homme Profil pro
    Étudiant
    Inscrit en
    Juin 2012
    Messages
    1 711
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Juin 2012
    Messages : 1 711
    Par défaut
    Citation Envoyé par the Hound Voir le message
    Le compilateur n'a aucune idée de ce qu'est {5, 6, 7, 8}.
    Le compilo sait très bien que c'est une std::initializer_list<int>.

    Mais les std::initializer_list<int> ne fournissent que des itérateurs pour un accès séquentiel, donc pas d'operator[] et pas de *(begin() + 3) non plus.

  5. #5
    Membre émérite
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Juin 2014
    Messages
    345
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Finance

    Informations forums :
    Inscription : Juin 2014
    Messages : 345
    Par défaut
    Citation Envoyé par Iradrille Voir le message
    Le compilo sait très bien que c'est une std::initializer_list<int>.
    J'ai simplifié au possible
    Mais ça n'a pas de valeur "sémantique" valide dans ce contexte : la std::initializer_list<> est conçue pour l'initialisation d'un objet, et pour rien d'autre.

  6. #6
    Membre confirmé
    Homme Profil pro
    Développeur du dimanche
    Inscrit en
    Février 2013
    Messages
    154
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur du dimanche

    Informations forums :
    Inscription : Février 2013
    Messages : 154
    Par défaut
    Mais les std::initializer_list<int> ne fournissent que des itérateurs pour un accès séquentiel, donc pas d'operator[] et pas de *(begin() + 3) non plus.
    Ça m'embête tout ça.. Y a-t-il espoir qu'une prochaine version du C++ offre de telles possibilités ?

  7. #7
    Membre Expert
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2011
    Messages
    760
    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 : 760
    Par défaut
    Citation Envoyé par Iradrille Voir le message
    Mais les std::initializer_list<int> ne fournissent que des itérateurs pour un accès séquentiel, donc pas d'operator[] et pas de *(begin() + 3) non plus.
    Les itérateurs fournit par std::initializer_list sont des pointeurs. Donc *(begin() + 3) est valide.

  8. #8
    Membre Expert
    Homme Profil pro
    Étudiant
    Inscrit en
    Juin 2012
    Messages
    1 711
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Juin 2012
    Messages : 1 711
    Par défaut
    Vu que initializer_list ne fourni pas d'operator[], je supposais que la manière dont était stockée les éléments n'était pas garanti et dépendait de l'implémentation (peut être implémenté comme un vector ou une list, ou autre).
    Et donc que les itérateurs fournis ne permettaient pas un accès aléatoire.

    Mais après lecture de la doc, les éléments sont forcément consécutifs en mémoire (style vector ou array) et les itérateurs fournis permettent un accès aléatoire (ce sont de simple pointeurs).

    Dans ce cas pourquoi est-ce-que
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    unsigned a = {5, 6, 7, 8}[3];
     
    // ou
    auto il = {5, 6, 7, 8};
    unsigned b = il[3];
    N'est pas valide ?

    Alors que
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    auto il = {5, 6, 7, 8};
    unsigned a = std::begin(il)[3];
    unsigned b = *(std::begin(il) + 3);
    L'est ?

    Quelle est la raison pour ne pas fournir d'operator[] ?

    C'est dangereux ce genre d'incohérence je trouve, si on veut le faire en 1 ligne on se retrouve face à une UB (je crois ? {5, 6, 7, 8} est détruit au retour de begin ?)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    unsigned a = *(std::begin({5, 6, 7, 8}) + 3);
    unsigned b = std::begin({5, 6, 7, 8})[3];

  9. #9
    Expert éminent

    Femme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2007
    Messages
    5 202
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Essonne (Île de France)

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

    Informations forums :
    Inscription : Juin 2007
    Messages : 5 202
    Par défaut
    Une valeur temporaire n'est détruite qu'à la fin de l'évaluation d'une expression complète, pas d'une expression locale.

    Pour le reste je ne sais pas trop, je n'ai jamais essayé de telles choses.

  10. #10
    Membre confirmé
    Homme Profil pro
    Développeur du dimanche
    Inscrit en
    Février 2013
    Messages
    154
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur du dimanche

    Informations forums :
    Inscription : Février 2013
    Messages : 154
    Par défaut
    Ce qui fait une magnifique transition pour ma question suivante !

    Je me suis appuyé sur le dernier code d'Iradrille, mais le code ne compile pas. Pourquoi ? (Calling a private constructor of class 'std::type_info')

    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 <typename...Ts>
    struct Test
    {
        void function(unsigned i)
        {
            std::cout<<(std::begin({typeid(Ts)...})[i]).name();
        }
    };
     
    int main()
    {
        Test<int,char,bool> test;
     
        test.function(2);
     
        return 0;
    }

  11. #11
    Membre Expert
    Homme Profil pro
    Étudiant
    Inscrit en
    Juin 2012
    Messages
    1 711
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Juin 2012
    Messages : 1 711
    Par défaut
    Parce que tu essaies de copier des type_info, c'est un type non copiable.

    Tu peux par contre copier le nom.
    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
    #include <iostream>
    #include <typeinfo>
     
    struct Foo {};
     
    template <typename...Ts>
    struct Test {
        void function(unsigned i) {
            std::cout << std::begin({typeid(Ts).name()...})[i];
        }
    };
     
    int main() {
        Test<int, char, bool, Foo> test;
        test.function(2);
        std::cout << '\n';
        test.function(3);
     
        return 0;
    }
    Résultat (gcc)

  12. #12
    Membre confirmé
    Homme Profil pro
    Développeur du dimanche
    Inscrit en
    Février 2013
    Messages
    154
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur du dimanche

    Informations forums :
    Inscription : Février 2013
    Messages : 154
    Par défaut
    Habile.. Merci !!

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

Discussions similaires

  1. [FAQ]Une entrée sur les listes d'initialisation
    Par koala01 dans le forum Contribuez
    Réponses: 2
    Dernier message: 04/03/2010, 09h24
  2. Commande date. Faire des opération sur l'heure?
    Par fidififouille dans le forum Linux
    Réponses: 9
    Dernier message: 23/08/2004, 15h16
  3. [Débutant][String] Opérations sur une chaîne
    Par gandalf_le_blanc dans le forum Général Java
    Réponses: 8
    Dernier message: 08/06/2004, 11h59
  4. operation sur des alias
    Par 74160 dans le forum Requêtes
    Réponses: 4
    Dernier message: 24/11/2003, 18h19
  5. [langage] random sur liste ou tableau
    Par martijan dans le forum Langage
    Réponses: 2
    Dernier message: 15/07/2003, 14h47

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