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 :

std::make_array pour c++14 ?


Sujet :

C++

  1. #1
    Membre confirm�
    Profil pro
    Inscrit en
    Avril 2009
    Messages
    199
    D�tails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2009
    Messages : 199
    Par d�faut std::make_array pour c++14 ?
    Bonjour � tous!

    Quelqu'un sait-il s'il existe une proposition pour std::make_array pour le futur standard c++? En effet il existe d�j� make_tuple par exemple qui permet de d�duire automatiquement le nombre d'argument, ce qui se r�v�le particuli�rement int�ressant!

    Le site http://www.meetingcpp.com/index.php/start.html qui recense pas mal de paper ne mentionne rien � ce sujet l�!

    Merci beaucoup � tous!

  2. #2
    Membre chevronn�

    Homme Profil pro
    D�veloppeur informatique
    Inscrit en
    Juin 2007
    Messages
    373
    D�tails du profil
    Informations personnelles :
    Sexe : Homme
    �ge : 36
    Localisation : Royaume-Uni

    Informations professionnelles :
    Activit� : D�veloppeur informatique
    Secteur : Sant�

    Informations forums :
    Inscription : Juin 2007
    Messages : 373
    Par d�faut
    Bonjour,

    On peut d�j� faire �a :
    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    std::array<float, 5> a1 = {{0.1, 0.2, 0.3, 0.4, 0.5}}; // possible en C++11
    std::array<float, 5> a2 = {0.1, 0.2, 0.3, 0.4, 0.5}; // suggéré pour la prochaine norme
    Tu voudrais pouvoir �crire quelque chose comme �a ?
    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    3
    auto a1 = std::make_array({0.1, 0.2, 0.3, 0.4, 0.5});
    // ... ou: 
    auto a2 = std::make_array(0.1, 0.2, 0.3, 0.4, 0.5);

  3. #3
    Membre confirm�
    Profil pro
    Inscrit en
    Avril 2009
    Messages
    199
    D�tails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2009
    Messages : 199
    Par d�faut
    Exactement! Je souhaiterais faire cela en fait :

    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    auto my_array = std::make_array(
        1,
        2,
     
    #if defined (MY_DEFINE)
        3,
    #endif
     
        4);
     
        for(auto const i& : my_array)
            // some code ...
    Sachant que le code qui suit la d�claration et l'initialisation de my_array ne d�pend en aucun cas du nombre d'�l�ments! Il reste donc valide!

  4. #4
    R�dacteur/Mod�rateur


    Homme Profil pro
    Network game programmer
    Inscrit en
    Juin 2010
    Messages
    7 153
    D�tails du profil
    Informations personnelles :
    Sexe : Homme
    �ge : 38
    Localisation : Canada

    Informations professionnelles :
    Activit� : Network game programmer

    Informations forums :
    Inscription : Juin 2010
    Messages : 7 153
    Billets dans le blog
    4
    Par d�faut
    Salut,

    Cette syntaxe ne fonctionnerait pas ?
    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    auto my_array = {{
        1,
        2,
     
    #if defined (MY_DEFINE)
        3,
    #endif
     
        4}};
    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.

  5. #5
    Membre confirm�
    Profil pro
    Inscrit en
    Avril 2009
    Messages
    199
    D�tails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2009
    Messages : 199
    Par d�faut
    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
    #include <array>
     
    int main()
    {
        auto my_array = {{
            1,
            2,
     
        #if defined (MY_DEFINE)
            3,
        #endif
     
            4}};
     
        for(auto &i : my_array)
        {
        }
    }
    Erreur de la part du compilateur :
    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    3
    4
    5
    6
    7
    g++ -o main.o -c main.cpp -W -Werror -Wall -Wfatal-errors -pedantic -pedantic-errors  -std=c++11
    main.cpp: In function ‘int main()’:
    main.cpp:13:11: error: unable to deduce ‘std::initializer_list<_Tp>’ from ‘{{1, 2, 4}}4}};
               ^
    compilation terminated due to -Wfatal-errors.
    make: *** [main.o] Error 1
    P.S. La sortie bizarre c'est gcc 4.8

  6. #6
    Membre chevronn�

    Homme Profil pro
    D�veloppeur informatique
    Inscrit en
    Juin 2007
    Messages
    373
    D�tails du profil
    Informations personnelles :
    Sexe : Homme
    �ge : 36
    Localisation : Royaume-Uni

    Informations professionnelles :
    Activit� : D�veloppeur informatique
    Secteur : Sant�

    Informations forums :
    Inscription : Juin 2007
    Messages : 373
    Par d�faut
    Voil� une impl�mentation qui fonctionne :
    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    3
    4
    template<typename T, typename ... Args>
    auto make_array(T t, Args ... args) -> std::array<T, sizeof...(Args)+1> {
        return std::array<T, sizeof...(Args)+1>({{t, args...}});
    }
    Il ne te reste plus qu'� �crire la proposition

  7. #7
    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
    Voila une id�e � garder sous la main.

  8. #8
    Membre Expert
    Avatar de Klaim
    Homme Profil pro
    D�veloppeur de jeux vid�o
    Inscrit en
    Ao�t 2004
    Messages
    1 717
    D�tails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activit� : D�veloppeur de jeux vid�o
    Secteur : High Tech - �diteur de logiciels

    Informations forums :
    Inscription : Ao�t 2004
    Messages : 1 717
    Par d�faut
    Je ne vois pas l'interet de make_array si il ne permet pas de definir la taille dynamiquement, au runtime.

  9. #9
    Membre chevronn�

    Homme Profil pro
    D�veloppeur informatique
    Inscrit en
    Juin 2007
    Messages
    373
    D�tails du profil
    Informations personnelles :
    Sexe : Homme
    �ge : 36
    Localisation : Royaume-Uni

    Informations professionnelles :
    Activit� : D�veloppeur informatique
    Secteur : Sant�

    Informations forums :
    Inscription : Juin 2007
    Messages : 373
    Par d�faut
    Je ne vois pas comment tu pourrais utiliser une syntaxe comme celle-ci avec un nombre d'argument d�fini au runtime. Autrement dit, qu'�crirais-tu ici:
    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    auto a = make_array(...);
    Sinon, l'int�r�t de std::array est justement d'avoir un tableau de taille fixe et connue � la compilation. Pour une taille fixe mais connue au runtime, il faudrait aller voir du c�t� de std::dynarray (�galement propos�e pour la prochaine norme). Mais tu peux y perdre en performance, j'imagine, car le compilateur a d'avantage de libert� quand la taille du tableau est connue � la compilation.

  10. #10
    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
    Dans int tab[]={1,2,3}; le compilateur connait la taille, pourquoi ne le pourrait-il pas pour make_array({1,2,3});?

    L'objectif de std::array est d'avoir la s�curit� d'une classe autour d'un tableau crocheteux.

  11. #11
    Membre Expert

    Homme Profil pro
    D�veloppeur informatique
    Inscrit en
    Septembre 2007
    Messages
    1 895
    D�tails du profil
    Informations personnelles :
    Sexe : Homme
    �ge : 49
    Localisation : France, Bouches du Rh�ne (Provence Alpes C�te d'Azur)

    Informations professionnelles :
    Activit� : D�veloppeur informatique
    Secteur : High Tech - Op�rateur de t�l�communications

    Informations forums :
    Inscription : Septembre 2007
    Messages : 1 895
    Par d�faut
    Citation Envoy� par Klaim Voir le message
    Je ne vois pas l'interet de make_array si il ne permet pas de definir la taille dynamiquement, au runtime.
    Un std::array dont la taille est d�termin�e au runtime s'appelle un std::vector

    J'aillais dire qu'un make_array() n'est pas n�cessairement une bonne chose, mais en m�me temps, je me suis dit ceci :

    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    3
    4
    5
     
    std::array<????, 2> array = { 
      [](int n) -> bool { return n & 1 ? true : false; },
      [](int n) -> bool { return n & 1 ? false : true; }
    };
    Quel est le type ???? ?

    En gros, make_array() pour des int, float, ... n'a pas grand int�r�t. Mais si on complexifie le type stock�, alors �a peut devenir int�ressant d'utiliser le m�canisme de d�duction de type propos� par le standard C++ en conjonction avec auto. Si on fabrique un array de lambda, c'est m�me obligatoire (et un array de lambda peut permettre de faire des choses originales).

    Citation Envoy� par Klaim
    Voil� une impl�mentation qui fonctionne :
    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    3
    4
    5
     
    template<typename T, typename ... Args>
    auto make_array(T t, Args ... args) -> std::array<T, sizeof...(Args)+1> {
        return std::array<T, sizeof...(Args)+1>({{t, args...}});
    }
    Il ne te reste plus qu'� �crire la proposition
    Je pencherais plut�t pour l'utilisation d'une liste d'initialiseurs (chrome me propose de changer ce mot par "administrationaliser" ; bien jou�, chrome...). Tous les arguments sont de m�me type apr�s tout.
    [FAQ des forums][FAQ D�veloppement 2D, 3D et Jeux][Si vous ne savez pas ou vous en �tes...]
    Essayez d'�crire clairement (c'est � dire avec des mots fran�ais complets). SMS est votre ennemi.
    Evitez les arguments inutiles - DirectMachin vs. OpenTruc ou G++ vs. Caf�. C'est d�pass� tout �a.
    Et si vous �tes sages, vous aurez peut �tre vous aussi la chance de passer � la t�l�. Ou pas.

    Ce site contient un forum d'entraide gratuit. Il ne s'use que si l'on ne s'en sert pas.

  12. #12
    Membre chevronn�

    Homme Profil pro
    D�veloppeur informatique
    Inscrit en
    Juin 2007
    Messages
    373
    D�tails du profil
    Informations personnelles :
    Sexe : Homme
    �ge : 36
    Localisation : Royaume-Uni

    Informations professionnelles :
    Activit� : D�veloppeur informatique
    Secteur : Sant�

    Informations forums :
    Inscription : Juin 2007
    Messages : 373
    Par d�faut
    Je ne pense pas qu'il soit possible d'avoir une liste d'initialisation {...} comme argument de make_array (si l'objectif est bel et bien de cr�er un std::array). Les deux prototypes possibles seraient :
    • std::array<T,N> make_array(std::initializer_list<T> v), mais il est impossible de d�terminer automatiquement N (limitation de std::initializer_list, je trouve �a dommage d'ailleurs),
    • ou encore std::array<T,N> make_array(const T (&v)[N]), mais je n'arrive pas � faire en sorte que le compilateur d�duise automatiquement T et/ou N. Quand bien m�me ce serait possible, la seule mani�re de construire un std::array � partir de l� serait de faire une boucle et d'assigner les �l�ments uns � uns. �a peut para�tre plus lourd � premi�re vue, mais (avec toutes les optimisations activ�es) gcc me g�n�re le m�me assembleur qu'avec le premier code que j'ai post�. Sans optimisation, il ex�cute la boucle aveugl�ment, �a sera donc moins performant.


    Si on se fiche d'avoir une taille connue � la compilation, alors le probl�me de l'OP ne se pose plus, et on peut �crire directement :
    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    3
    4
    5
    6
    7
    std::vector<float> v = {
        1.0f,
    #ifdef TODO
        2.0f,
    #endif
        3.0f
    };
    Pas besoin d'un make_array ici.

  13. #13
    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
    comment ca, impossible?
    Et std::initializer_list::size(), c'est pour quoi faire, dans ce cas?

    A tout hasard, une breve question � Notre-Ami-a-Tous (c++11 make_array) m'a donn� ceci (github) et cela (stackoverflow)

    et aussi une boost proposal

  14. #14
    Membre confirm�
    Profil pro
    Inscrit en
    Avril 2009
    Messages
    199
    D�tails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2009
    Messages : 199
    Par d�faut
    Je pense qu'il voulait dire que std::initializer_list::size() ne peut pas �tre utiliser pour d�duire l'argument N de std::array<T, N>.

  15. #15
    Membre chevronn�

    Homme Profil pro
    D�veloppeur informatique
    Inscrit en
    Juin 2007
    Messages
    373
    D�tails du profil
    Informations personnelles :
    Sexe : Homme
    �ge : 36
    Localisation : Royaume-Uni

    Informations professionnelles :
    Activit� : D�veloppeur informatique
    Secteur : Sant�

    Informations forums :
    Inscription : Juin 2007
    Messages : 373
    Par d�faut
    Exactement. La taille d'une std::initializer_list<T> n'est pas un param�tre template, et std::initializer_list<T>::size() n'est pas constexpr.
    Les version qui sont cit�es dans le dernier post de leternel reposent sur le m�me principe que ce que j'ai propos�, si ce n'est qu'elles sont plus compl�tes et plus performantes (perfect forwarding).

  16. #16
    Membre Expert
    Avatar de Klaim
    Homme Profil pro
    D�veloppeur de jeux vid�o
    Inscrit en
    Ao�t 2004
    Messages
    1 717
    D�tails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activit� : D�veloppeur de jeux vid�o
    Secteur : High Tech - �diteur de logiciels

    Informations forums :
    Inscription : Ao�t 2004
    Messages : 1 717
    Par d�faut
    Citation Envoy� par Emmanuel Deloget Voir le message
    Un std::array dont la taille est d�termin�e au runtime s'appelle un std::vector
    Oui mais en meme temps je n'ai pas parle d'allocation.
    Le debat a lieu en ce moment dans le groupe de discussion du standard a propos de dynarray, comme quoi il devrais allouer sur la pile ou sur le tas...

    Perso, tant que je peux allouer une quantitee fixe et etre garanti que ca ne bougera jamais, ca m'eviterai d'avoir a construire des helpers autour de std::vector.

  17. #17
    gl
    gl est d�connect�
    R�dacteur

    Homme Profil pro
    Inscrit en
    Juin 2002
    Messages
    2 165
    D�tails du profil
    Informations personnelles :
    Sexe : Homme
    �ge : 46
    Localisation : France, Is�re (Rh�ne Alpes)

    Informations forums :
    Inscription : Juin 2002
    Messages : 2 165
    Par d�faut
    Citation Envoy� par Emmanuel Deloget Voir le message
    Un std::array dont la taille est d�termin�e au runtime s'appelle un std::vector
    Pas n�cessairement, tu peux vouloir un conteneur dont la taille est fix�e � la construction sans pour autant que cette taille ne soit connu lors de la compilation (par ex. si elle est lue en conf).

    Ce n'est pas quelque chose dont j'aurais besoin tout les jours mais je con�ois que l'on puisse avoir ce besoin.

  18. #18
    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 Emmanuel Deloget Voir le message
    En gros, make_array() pour des int, float, ... n'a pas grand int�r�t. Mais si on complexifie le type stock�, alors �a peut devenir int�ressant d'utiliser le m�canisme de d�duction de type propos� par le standard C++ en conjonction avec auto. Si on fabrique un array de lambda, c'est m�me obligatoire (et un array de lambda peut permettre de faire des choses originales).
    C'est possible un array de lambda ? (�a devrait, mais impossible de compiler chez moi, ni sur VS2012, ni sur gcc 4.8.0)
    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    template<typename T, typename ... Args>
    auto make_array(T t, Args ... args) -> std::array<T, sizeof...(Args)+1> {
    	return std::array<T, sizeof...(Args)+1>({{t, args...}});
    }
     
    int main() {
    	auto f = [](int i)->int { return i; };
    	auto f2 = [](int i)->int { return i*2; };
     
    	std::array<decltype(f), 2> arr = {{ f, f2 }};
    	auto arr2 = make_array(f, f2);
     
    	return 0;
    }
    Mais au moins l'erreur est originale
    il n'existe aucune conversion d�finie par l'utilisateur appropri�e de "lambda []int (int i)->int" en "lambda []int (int i)->int"

  19. #19
    R�dacteur/Mod�rateur


    Homme Profil pro
    Network game programmer
    Inscrit en
    Juin 2010
    Messages
    7 153
    D�tails du profil
    Informations personnelles :
    Sexe : Homme
    �ge : 38
    Localisation : Canada

    Informations professionnelles :
    Activit� : Network game programmer

    Informations forums :
    Inscription : Juin 2010
    Messages : 7 153
    Billets dans le blog
    4
    Par d�faut
    Citation Envoy� par gl Voir le message
    Pas n�cessairement, tu peux vouloir un conteneur dont la taille est fix�e � la construction sans pour autant que cette taille ne soit connu lors de la compilation (par ex. si elle est lue en conf).
    C'est exactement ce que fait vector, il a m�me un constructeur fait pour �a : std::vector(size_type n);
    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.

  20. #20
    gl
    gl est d�connect�
    R�dacteur

    Homme Profil pro
    Inscrit en
    Juin 2002
    Messages
    2 165
    D�tails du profil
    Informations personnelles :
    Sexe : Homme
    �ge : 46
    Localisation : France, Is�re (Rh�ne Alpes)

    Informations forums :
    Inscription : Juin 2002
    Messages : 2 165
    Par d�faut
    Citation Envoy� par Bousk Voir le message
    C'est exactement ce que fait vector, il a m�me un constructeur fait pour �a : std::vector(size_type n);
    Non ce n'est pas exactement ce que fait vector. La taille n'est pas fix�e � la construction.
    Tu peux certes r�server une certaine taille � la construction (ou via un appel � reserve()) mais cela ne fixe pas la taille d�finitivement, celle-ci est susceptible d'�voluer par la suite (construit un vector d'une taille 10 et ins�re 11 �l�ments par push_back : �a fonctionne tr�s bien et la taille du vector est bel et bien sup�rieure � 10).
    Fondamentalement, la taille d'un vector est dynamique. Un array a fondamentalement une taille fixe lui mais cela ne signifie pas n�cessairement que celle-ci doit �tre connu � la compilation (comme dans le cas de std::array), il est tout � fait envisageable de souhaiter un array (avec une taille fixe donc) dont la taille n'est connue qu'au runtime (n'est-ce pas la raison d'�tre des VLA en C ? M�me si je n'appr�cie pas la fa�on dont ils sont d�finis, il remplisse bel et bien ce r�le).

Discussions similaires

  1. Utilisation de std::function pour cr�er un bouton
    Par Invit� dans le forum SL & STL
    R�ponses: 19
    Dernier message: 28/09/2014, 17h12
  2. std::allocator pour char et wchar_t
    Par Meseira dans le forum SL & STL
    R�ponses: 6
    Dernier message: 24/04/2013, 14h20
  3. Probl�me avec std::stringstream pour lire un fichier OBJ
    Par Kromagg dans le forum D�veloppement 2D, 3D et Jeux
    R�ponses: 3
    Dernier message: 01/12/2010, 18h49
  4. pr�dicat pour min_element d'une std::map
    Par Kurisu dans le forum SL & STL
    R�ponses: 6
    Dernier message: 11/09/2006, 19h27
  5. R�ponses: 22
    Dernier message: 26/08/2005, 12h46

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