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 :

Problème de variables constantes


Sujet :

C++

  1. #1
    Nouveau Candidat au Club
    Homme Profil pro
    Étudiant
    Inscrit en
    September 2023
    Messages
    4
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : September 2023
    Messages : 4
    Points : 1
    Points
    1
    Par défaut Problème de variables constantes
    Bonjour à tous,

    Programmeur depuis plusieurs années sur des langages haut niveau (comme Python ou PHP) j'essaie de me mettre au C++. Jusqu'à présent c'était compliqué mais je m'en sortais, jusqu'à ce que j'essaie de travailler avec des tableaux statiques. Je vous explique mon problème : j'ai une classe à qui je souhaite transmettre en paramètre (par le constructeur) une donnée parfaitement constante (un std::size_t fixé dans le code) pour qu'elle l'utilise pour créer un tableau statique (std::array). J'ai tout essayé, jusqu'au const std::size_t* const mais toujours la même erreur "Non-type template argument is not a constant expression"... Bien sûr, je sais que je peux contourner, passer directement le tableau en référence ou essayer une template mais ma curiosité intellectuelle me force à me tourner vers vous, fins connaisseurs, pour savoir ce que je rate : en substance, comment faire pour préserver le caractère constant d'une variable en la passant à une fonction.

    Je vous mets un exemple de ce que j'essaie de faire :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    class MaSuperClasse {
      ...
        inline MaSuperClasse(const std::size_t &size) {
            std::array<int, size> monmagnifiquetableau;
        };
    };
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    const std::size_t size = 1;
    MaSuperClasse masuperinstance(size);
    Je vous remercie tous d'avance pour votre aide !

  2. #2
    Rédacteur/Modérateur


    Homme Profil pro
    Network game programmer
    Inscrit en
    June 2010
    Messages
    7 095
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : Canada

    Informations professionnelles :
    Activité : Network game programmer

    Informations forums :
    Inscription : June 2010
    Messages : 7 095
    Points : 32 842
    Points
    32 842
    Billets dans le blog
    4
    Par défaut
    std::array prend sa taille en paramètre de compilation template, pas avec une variable
    Pensez à consulter la FAQ ou les cours et tutoriels de la section C++.
    Un peu de programmation réseau ?
    Aucune aide via MP ne sera dispensée. Merci d'utiliser les forums prévus à cet effet.

  3. #3
    Nouveau Candidat au Club
    Homme Profil pro
    Étudiant
    Inscrit en
    September 2023
    Messages
    4
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : September 2023
    Messages : 4
    Points : 1
    Points
    1
    Par défaut
    Citation Envoyé par Bousk Voir le message
    std::array prend sa taille en paramètre de compilation template, pas avec une variable
    Merci de la réponse.
    Il n'y a donc aucun moyen de faire autrement ? Même avec une sorte de variable qu'on établirait comme constante ? Je n'arrive pas à imaginer qu'il n'y ait aucun moyen de contourner...

  4. #4
    Expert éminent sénior
    Homme Profil pro
    Analyste/ Programmeur
    Inscrit en
    July 2013
    Messages
    4 579
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Analyste/ Programmeur

    Informations forums :
    Inscription : July 2013
    Messages : 4 579
    Points : 10 406
    Points
    10 406
    Par défaut
    Je ne comprends pas à 100% ton problème mais tu n'utilises pas le bon conteneur.
    standard containers, documentation cplusplus.com en anglais
    Il faut utiliser 1 std::vector qui est 1 tableau dynamique

    Même en C, 1 tableau statique doit connaître sa taille à la compilation, sauf les VLA (variable-length array) qui ont été dépréciés avec le C11.

    std::array est 1 wrapper autour d'1 tableau X[].

  5. #5
    Expert éminent
    Homme Profil pro
    Ingénieur développement matériel électronique
    Inscrit en
    December 2015
    Messages
    1 533
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 60
    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 : December 2015
    Messages : 1 533
    Points : 7 502
    Points
    7 502
    Par défaut
    Il faut distinguer constante (qui ne change plus après sa création) et constante de compilation. Pour les types comme std::array<>, la taille doit être une constante de compilation.
    On peut écrire:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    template<std::size_t Size>
    class MaSuperClasse {                               // MaSuperClasse nécessite une constante de compilation Size
    public:
        MaSuperClasse() {
            std::array<int,Size> monmagnifiquetableau;  // Peut définir la taille d'un std::array<>
        }
    };
     
    int  main() {
       constexpr std::size_t  size = 1;        // size est constante de compilation
       MaSuperClasse<size>  masuperinstance{}; // qui peut définir une MaSuperClasse<>
    }
    Mais utiliser un std::vector<> de taille dynamique est très souvent plus adapté.

  6. #6
    Nouveau Candidat au Club
    Homme Profil pro
    Étudiant
    Inscrit en
    September 2023
    Messages
    4
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : September 2023
    Messages : 4
    Points : 1
    Points
    1
    Par défaut
    Je vous remercie de vos réponses. Toutefois, je m'inquiète un peu car j'avais lu que l'objet std::vector était bien plus gourmand que std::array. Est-ce vrai ? la différence est-elle perceptible selon vous?

  7. #7
    Expert éminent
    Homme Profil pro
    Ingénieur développement matériel électronique
    Inscrit en
    December 2015
    Messages
    1 533
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 60
    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 : December 2015
    Messages : 1 533
    Points : 7 502
    Points
    7 502
    Par défaut
    Citation Envoyé par aldric-l Voir le message
    Je vous remercie de vos réponses. Toutefois, je m'inquiète un peu car j'avais lu que l'objet std::vector était bien plus gourmand que std::array. Est-ce vrai ? la différence est-elle perceptible selon vous?
    Gourmand en quoi?

    Consommation mémoire? Par exemple pour un tableau de 100 double.
    - std::array<> nécessite 8*100=800 octets.
    - std::vector<> demande des octets de gestion et une allocation dynamique donc environ 8*100+20=820 octets

    Temps d'accès à un élément? Ou tout algorithme (tri ...)?
    Equivalents

    Charge pour copier?
    - std::array<> on doit copier 800 octets.
    - std::vector<> on doit copier 820 octets et faire une allocation dynamique.

    Charge pour transférer?
    - std::array<> ne supporte pas le transfert, on doit copier 800 octets
    - std::vector<> juste 12 octets à copier. Gain flagrant pour le std::vector<>.

    Autres contraintes?
    - std::array<> en variable consomme de la pile, donc impossible de créer un grand std::array<> et éviter de le passer sa valeur en paramètre de fonction.
    - std::vector<> est dynamique, peut poser des problèmes dans les systèmes embarqués à très fortes contraintes.

    En résumé:
    Le std::vector<> presque toujours plus d'avantages que le std::array<>. Le std::array<> n'est à préférer que si on a à la fois:
    - le tableau est petit
    - sa taille est fixe et est connue à la compilation.

  8. #8
    Nouveau Candidat au Club
    Homme Profil pro
    Étudiant
    Inscrit en
    September 2023
    Messages
    4
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : September 2023
    Messages : 4
    Points : 1
    Points
    1
    Par défaut
    Citation Envoyé par dalfab Voir le message
    Gourmand en quoi?

    Consommation mémoire? Par exemple pour un tableau de 100 double.
    - std::array<> nécessite 8*100=800 octets.
    - std::vector<> demande des octets de gestion et une allocation dynamique donc environ 8*100+20=820 octets

    Temps d'accès à un élément? Ou tout algorithme (tri ...)?
    Equivalents

    Charge pour copier?
    - std::array<> on doit copier 800 octets.
    - std::vector<> on doit copier 820 octets et faire une allocation dynamique.

    Charge pour transférer?
    - std::array<> ne supporte pas le transfert, on doit copier 800 octets
    - std::vector<> juste 12 octets à copier. Gain flagrant pour le std::vector<>.

    Autres contraintes?
    - std::array<> en variable consomme de la pile, donc impossible de créer un grand std::array<> et éviter de le passer sa valeur en paramètre de fonction.
    - std::vector<> est dynamique, peut poser des problèmes dans les systèmes embarqués à très fortes contraintes.

    En résumé:
    Le std::vector<> presque toujours plus d'avantages que le std::array<>. Le std::array<> n'est à préférer que si on a à la fois:
    - le tableau est petit
    - sa taille est fixe et est connue à la compilation.
    C'est très clair merci beaucoup, je vais pouvoir me débarrasser de mes std::array dans de nombreux cas alors !

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

Discussions similaires

  1. [ZF1.9.2]Problème avec lecture variable constante
    Par vince29 dans le forum Zend Framework
    Réponses: 2
    Dernier message: 28/02/2011, 10h32
  2. [Debutant(e)]problème de variable d'environnement
    Par tolsam dans le forum Eclipse Java
    Réponses: 1
    Dernier message: 12/08/2004, 20h08
  3. Problème de variable
    Par vp dans le forum Windows
    Réponses: 2
    Dernier message: 14/05/2004, 17h27
  4. [Débutant] Problème de variables
    Par bonnefr dans le forum SWT/JFace
    Réponses: 9
    Dernier message: 12/05/2004, 18h41
  5. [servlet]problème de variable jamais nulle
    Par omega dans le forum Servlets/JSP
    Réponses: 2
    Dernier message: 18/03/2004, 10h31

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