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 :

Accès à un tableau static constexpr


Sujet :

Langage C++

  1. #1
    Membre éclairé

    Homme Profil pro
    Non disponible
    Inscrit en
    Décembre 2012
    Messages
    478
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Non disponible

    Informations forums :
    Inscription : Décembre 2012
    Messages : 478
    Points : 877
    Points
    877
    Billets dans le blog
    1
    Par défaut Accès à un tableau static constexpr
    Bonjour,

    Je n'arrive pas à comprendre un truc "bizarre" dans ces conditions bien particulières.

    J'ai épuré au maximum le code, quelqu'un pourrait-il, s'il vous plait, m'expliquer pourquoi le compilo me balance : undefined reference to `Quad::tab' pour ce 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
    struct Pos { int pos; };
    //------------------------------------------------------------------------------
    struct Quad
    {
        Quad() { foo(); }
        static constexpr Pos tab[1] = {{ 1 }};
        void foo() { Pos copy = tab[0]; }
    };
    //------------------------------------------------------------------------------
    int main()
    {
        Quad();
        return 0;
    }
    Merci.

  2. #2
    Expert éminent sénior

    Femme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2007
    Messages
    5 189
    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 189
    Points : 17 141
    Points
    17 141
    Par défaut
    Oui, la définition d'une variable statique ne peut pas être dans la déclaration du type.

    il faut procéder ainsi:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    class A {
    static const int i;
    }
     
    const int A::i = 1;
    Qui plus est, la définition de la variable statique ne peut apparaître que dans une unique unité de compilation, donc pas dans un en-tête.
    Cela dit, dans ton exemple simplifiée, c'est bien le cas.
    Mes principes de bases du codeur qui veut pouvoir dormir:
    • Une variable de moins est une source d'erreur en moins.
    • Un pointeur de moins est une montagne d'erreurs en moins.
    • Un copier-coller, ça doit se justifier... Deux, c'est un de trop.
    • jamais signifie "sauf si j'ai passé trois jours à prouver que je peux".
    • La plus sotte des questions est celle qu'on ne pose pas.
    Pour faire des graphes, essayez yEd.
    le ter nel est le titre porté par un de mes personnages de jeu de rôle

  3. #3
    Membre éclairé

    Homme Profil pro
    Non disponible
    Inscrit en
    Décembre 2012
    Messages
    478
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Non disponible

    Informations forums :
    Inscription : Décembre 2012
    Messages : 478
    Points : 877
    Points
    877
    Billets dans le blog
    1
    Par défaut
    Bonjour Leternel, merci pour ta réponse.

    Mais j'ai c++11, et je peux déclarer les membres en static constexpr :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    #include <iostream>
    //------------------------------------------------------------------------------
    struct Struct
    {
        static constexpr int tab[4] = { 1, 2, 3, 4  };
    };
    //------------------------------------------------------------------------------
    int main()
    {
        std::cout << Struct::tab[3];
    	return 0;
    }
    console: 4

    Cependant, avec le cas précis du code plus haut, c'est impossible..

  4. #4
    Membre actif

    Homme Profil pro
    autodidacte
    Inscrit en
    Mars 2011
    Messages
    95
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : autodidacte

    Informations forums :
    Inscription : Mars 2011
    Messages : 95
    Points : 207
    Points
    207
    Par défaut
    La signification par défaut de chaque opération générée, comme implémentée telle que le compilateur la génère, est d'appliquer l'opération à tous les membres de base et non-statiques de la classe.

    (Source: Dans la 4è édition de Stroustrup (p519) : 17.6 Generating default operations)

    tab[0] est statique.

    En espérant t'aider, même s'il y a peu de chances
    Toujours à adapter le problème à la structure de la machine, mais se soigne pour faire l'inverse.

  5. #5
    Membre éclairé

    Homme Profil pro
    Non disponible
    Inscrit en
    Décembre 2012
    Messages
    478
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Non disponible

    Informations forums :
    Inscription : Décembre 2012
    Messages : 478
    Points : 877
    Points
    877
    Billets dans le blog
    1
    Par défaut
    Merci à toi Lautrec1, j'avoue ne pas saisir le sens de cette phrase..

    Le problème ne semble pas être seulement dû au static vu que ce code complie :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    struct Pos { int pos; };
    //------------------------------------------------------------------------------
    struct Quad
    {
        Quad() { foo(); }
        static constexpr Pos pos = { 1 };
        void foo() { Pos copy = pos; }
    };
    //------------------------------------------------------------------------------
    int main()
    {
        Quad();
        return 0;
    }

  6. #6
    Membre actif

    Homme Profil pro
    autodidacte
    Inscrit en
    Mars 2011
    Messages
    95
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : autodidacte

    Informations forums :
    Inscription : Mars 2011
    Messages : 95
    Points : 207
    Points
    207
    Par défaut
    Ca ne t'aide donc pas.
    En effet dans un livre de 2000 et moins bien côté:
    "Le compilateur génère un opérande d'affectation par défaut, c'est-à-dire une fonction membre opérateur correspondante publique, à condition que la classe contienne des membres non statiques, constantes ou références"
    Ca doit donc marcher ici.

    Citation Envoyé par PilloBuenaGente Voir le message
    Merci à toi Lautrec1, j'avoue ne pas saisir le sens de cette phrase..
    Je te mets la version en VO,pour être complet.

    "By default, a class provides:
    - A default constructor
    - A copy constructor
    - A copy assignment
    - A move constructor
    - A move assignment
    - A destructor

    The default meaning of each generated operation, as implemented when the compiler generates it, is to apply the operation to each base and non-static data member of the class. That is, we get memberwise copy, memberwise default construction, etc..."

    L'extrait de Stoustrup ne précise pas ce qui se passe si un seul membre de la classe est static.

    EDIT : orthographe
    Toujours à adapter le problème à la structure de la machine, mais se soigne pour faire l'inverse.

  7. #7
    Membre éclairé

    Homme Profil pro
    Non disponible
    Inscrit en
    Décembre 2012
    Messages
    478
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Non disponible

    Informations forums :
    Inscription : Décembre 2012
    Messages : 478
    Points : 877
    Points
    877
    Billets dans le blog
    1
    Par défaut
    Merci à toi de ne pas perdre patience..
    Ce coup ci je pense avoir compris
    La classe en question ne rentre donc pas dans ces critères..

    Edit : Je me suis permis de changer le titre, car ce n'est pas seulement pour une copie, mais même pour un simple accès ça bloque..

    Le problème se déplace...

    Pour la même classe Pos et le même main :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    struct Pos { const int pos; };
    //------------------------------------------------------------------------------
    int main()
    {
        Quad();
        return 0;
    }
    tableau d'une case OK
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    struct Quad
    {
        Quad() { foo(1, 0); }
        static constexpr Pos tab[1] = {{ 1 }};
        Pos foo(const int pos, const int index) { return { pos + tab[index].pos }; }
    };
    plusieurs cases ERROR
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    struct Quad
    {
        Quad() { foo(1, 0); }
        static constexpr Pos tab[2] = {{ 1 }, { 2 }};
        Pos foo(const int pos, const int index) { return { pos + tab[index].pos }; }
    };
    mais avec un accès par constexpr OK
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    struct Quad
    {
        Quad() { foo(1); }
        static constexpr Pos tab[2] = {{ 1 }, { 2 }};
        Pos foo(const int pos) { return { pos + tab[1].pos }; }
    };

  8. #8
    Membre éclairé

    Homme Profil pro
    Non disponible
    Inscrit en
    Décembre 2012
    Messages
    478
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Non disponible

    Informations forums :
    Inscription : Décembre 2012
    Messages : 478
    Points : 877
    Points
    877
    Billets dans le blog
    1
    Par défaut
    Je n'avais pas suffisamment creusé..

    En fait ceci ne compile pas non plus :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    struct Quad
    {
        Quad() { foo(1, 0); }
        static constexpr int tab[3] = { 1, 2, 3 };
        int foo(const int pos, const int index) { return { pos + tab[index] }; }
    };
    //------------------------------------------------------------------------------
    int main()
    {
        Quad();
        return 0;
    }
    C'est donc; l'accès à un tableau constexpr doit ce faire avec une valeur constexpr.

    Ceci n'était pas viable, sans doute que le compilo transforme ce tableau en simple valeur.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    struct Quad
    {
        Quad() { foo(1, 0); }
        static constexpr Pos tab[1] = {{ 1 }}; // Ce traduit par un simple static constexpr Pos tab = { 1 };
        Pos foo(const int pos, const int index) { return { pos + tab[index].pos }; }
    };
    Merci du temps passé en tout cas !

    edit dois-je rechanger le titre du post ?
    reedit changé

  9. #9
    Membre éclairé

    Homme Profil pro
    Non disponible
    Inscrit en
    Décembre 2012
    Messages
    478
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Non disponible

    Informations forums :
    Inscription : Décembre 2012
    Messages : 478
    Points : 877
    Points
    877
    Billets dans le blog
    1
    Par défaut
    Du nouveau !

    En cherchant "static array constexpr" je suis tombé sur ça.

    Il suffit juste de déclarer ce membre dans l'espace global.(Comme le faisait remarqué Leternel, sauf qu'avec static constexpr, on peut le définir au sein de la classe).

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    struct Quad
    {
        Quad() { foo(1, 0); }
        static constexpr int tab[3] = { 1, 2, 3 };
        int foo(const int pos, const int index) { return { pos + tab[index] }; }
    };
    constexpr int Quad::tab[3];
    //------------------------------------------------------------------------------
    int main()
    {
        Quad();
        return 0;
    }
    Sauvé !

  10. #10
    Expert éminent sénior

    Femme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2007
    Messages
    5 189
    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 189
    Points : 17 141
    Points
    17 141
    Par défaut
    Je m'en souviendrai, c'est intéressant.

    Merci pour l'information
    Mes principes de bases du codeur qui veut pouvoir dormir:
    • Une variable de moins est une source d'erreur en moins.
    • Un pointeur de moins est une montagne d'erreurs en moins.
    • Un copier-coller, ça doit se justifier... Deux, c'est un de trop.
    • jamais signifie "sauf si j'ai passé trois jours à prouver que je peux".
    • La plus sotte des questions est celle qu'on ne pose pas.
    Pour faire des graphes, essayez yEd.
    le ter nel est le titre porté par un de mes personnages de jeu de rôle

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

Discussions similaires

  1. Accès à une méthode static
    Par demcoul dans le forum Langage
    Réponses: 3
    Dernier message: 22/03/2007, 17h55
  2. Réponses: 1
    Dernier message: 23/09/2006, 00h41
  3. pb d'accès à un tableau associatif
    Par nixonne dans le forum Langage
    Réponses: 15
    Dernier message: 11/05/2006, 01h40
  4. Tableau static
    Par raynox dans le forum C++
    Réponses: 15
    Dernier message: 27/04/2006, 08h22
  5. [Débutant(e)][embarqué] Base de données vs tableau static
    Par ludonantes dans le forum Collection et Stream
    Réponses: 16
    Dernier message: 15/02/2006, 20h42

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