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] Initializer lists et héritage


Sujet :

Langage C++

  1. #1
    Membre chevronné
    Avatar de Florian Goo
    Profil pro
    Inscrit en
    Septembre 2008
    Messages
    680
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Septembre 2008
    Messages : 680
    Par défaut [C++0x] Initializer lists et héritage
    Bonjour à tous,

    J'ai compilé GCC 4.4 qui offre dores et déjà la délicieuse fonctionnalité des listes d'initialisation.

    Elle permet que faire de chouettes choses telles que :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    struct test
    {
        int i;
        int j;
    };
     
    int main(int argc, char **argv)
    {
        test t{0, 1};
     
        return 0;
    }
    Ce code compile avec ma version de GCC 4.4.

    Malheureusement, ça ne veut déjà plus compiler dans ce cas :
    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 empty_class
    {
    };
     
    struct test: public empty_class
    {
        int i;
        int j;
    };
     
    int main(int argc, char **argv)
    {
        test t{0, 1};
     
        return 0;
    }
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    no matching function for call to 'test::test(<brace-enclosed initializer list>)'
    note: candidates are: test::test()
    note:                 test::test(const test&)
    J'imagine alors qu'empty class est un élément comme un autre à initialiser, mais cette naïve tentative de correction mène à la même erreur :
    Je m'estimerais heureux d'avoir une réponse vu que peu de personnes doivent avoir de l'expérience dans la pratique du futur standard, alors merci d'avoir pris la peine de lire jusque là
    Cours : Initiation à CMake
    Projet : Scalpel, bibliothèque d'analyse de code source C++ (développement en cours)
    Ce message a été tapé avec un clavier en disposition bépo.

  2. #2
    Membre Expert
    Avatar de coyotte507
    Profil pro
    Inscrit en
    Octobre 2006
    Messages
    1 327
    Détails du profil
    Informations personnelles :
    Âge : 35
    Localisation : France

    Informations forums :
    Inscription : Octobre 2006
    Messages : 1 327
    Par défaut
    Salut,

    moi non plus je ne m'y connais pas trop dans le nouveau standard.

    Apparemment, quand on utilise une initializer-list qui ne correspond à aucun constructeur défini avec, cela revient à faire:

    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
    struct empty_class
    {
    };
     
    struct test: public empty_class
    {
        int i;
        int j;
    };
     
    int main(int argc, char **argv)
    {
        test t = {0, 1};
     
        return 0;
    }
    avec le "=", à la mode C.

    D'ailleurs, si on rajoute le "=", le compilateur est assez explicite:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    error: `t' must be initialized by constructor, not by `{...}'
    Dans ton cas, ce n'est pas gênant d'utiliser une liste d'initialisation (empty-class ne possède pas d'éléments), mais en général, si:

    Les éléments d'une classe de base doivent être initialisés indépendamment de ceux de la classe dérivée (il peut y avoir un constructeur propre à la classe de base etc.), c'est sûrement ce qui cause ton erreur.

    Voilà, je te donne ma propre interprétation, le C++ interdisant déjà le = {...} sur des classes dérivées, il interdit maintenant aussi le {...}

  3. #3
    Membre chevronné
    Avatar de Florian Goo
    Profil pro
    Inscrit en
    Septembre 2008
    Messages
    680
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Septembre 2008
    Messages : 680
    Par défaut
    Je précise que le premier code compile sans aucun problème ! Je viens de modifier mon premier post pour le dire explicitement.

    Comme tu le dis dans mon cas ce n'est pas gênant parce que empty_class est vide, mais dans la pratique il se peut qu'une classe parent soit effectivement vide. C'est le cas avec une interface par exemple.
    Cours : Initiation à CMake
    Projet : Scalpel, bibliothèque d'analyse de code source C++ (développement en cours)
    Ce message a été tapé avec un clavier en disposition bépo.

  4. #4
    Membre Expert
    Avatar de coyotte507
    Profil pro
    Inscrit en
    Octobre 2006
    Messages
    1 327
    Détails du profil
    Informations personnelles :
    Âge : 35
    Localisation : France

    Informations forums :
    Inscription : Octobre 2006
    Messages : 1 327
    Par défaut
    Citation Envoyé par Florian Goo Voir le message
    Je précise que le premier code compile sans aucun problème ! Je viens de modifier mon premier post pour le dire explicitement.
    Je suis d'accord!

    Ce code aussi marche parfaitement, en C++ normal:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    struct test
    {
        int i;
        int j;
    };
     
    int main(int argc, char **argv)
    {
        test t = {0, 1};
     
        return 0;
    }
    Ce que je veux dire, c'est qu'en l'absence de constructeur ayant pour paramètre les mêmes choses que dans la liste d'initialisation, ou en l'absence d'un constructeur prenant en paramètre une liste d'initialisation, le code C++0x:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    struct T
    {
        montype a;
        montype2 b;
        ...
    }
     
    T t {a, b, ...};
    est équivalent à:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    struct T
    {
        montype a;
        montype2 b;
        ...
    }
     
    T t = {a, b, ...};
    Et le C++ n'autorise déjà pas cet utilisation pour des classes dérivées, d'où ton problème. Je reconnais que normalement le compilateur devrait autoriser ça avec des classes de bases vides et sans constructeurs, mais c'est un peu lourd à gérer pour un compilateur et ce n'est pas moi qui fait la norme...

  5. #5
    Membre chevronné
    Avatar de Florian Goo
    Profil pro
    Inscrit en
    Septembre 2008
    Messages
    680
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Septembre 2008
    Messages : 680
    Par défaut
    Ah oui, d'accord. J'avais mal compris, je ne savais pas que c'était possible de faire ça en C++98 !

    Diantre

    Bon, effectivement, ça fonctionne si j'écris un constructeur explicite donc ça ne fait rien de plus méchant que d'augmenter la verbosité.
    Tant pis ! Merci pour ta réponse

    Je laisse non-résolu, à tout hasard.
    Cours : Initiation à CMake
    Projet : Scalpel, bibliothèque d'analyse de code source C++ (développement en cours)
    Ce message a été tapé avec un clavier en disposition bépo.

Discussions similaires

  1. Listes imbriquées - héritage CSS
    Par Hemgé dans le forum Mise en page CSS
    Réponses: 3
    Dernier message: 05/02/2009, 13h36
  2. [C++0x] Initializer lists et «foo f{};» vs «new foo{};»
    Par Florian Goo dans le forum Langage
    Réponses: 5
    Dernier message: 06/10/2008, 18h26
  3. Réponses: 3
    Dernier message: 06/11/2007, 09h29
  4. empecher héritage dans liste à puce imbriquées
    Par zamanika dans le forum Mise en page CSS
    Réponses: 2
    Dernier message: 15/03/2007, 15h18
  5. Héritage et listes chainées...
    Par syntaxerror dans le forum C++
    Réponses: 7
    Dernier message: 04/05/2005, 20h18

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