Partage
  • Partager sur Facebook
  • Partager sur Twitter

Initialisation d'un std::array<>

Avec une classe sans constructeur par défaut, ni de copie

    8 juillet 2019 à 14:20:46

    Bonjour à tous,

    J’ai besoin d'initialiser un std::array<> d’une taille définie par une template contenant des instances d’une classe ne possédant pas de constructeur par défaut, ni de constructeur de copie.

    J’ai donc quelque chose qui ressemble à :

    template<typename T, size_t N>
    static void executer(Parametre &p) {
        std::array<Processus<T>, N> processus {creer_des_processus<T, N>(p)};
    }
    

    Pour la fonction cree_des_processus(), je me suis basé sur cette réponse sur StackOverflow (j’ai adapté make_foos() pour prendre des paramètres, par exemple).  Du coup, chez moi, j’ai ça :

    template<typename T, size_t... Is>
    static std::array<Processus<T>, sizeof...(Is)> creer_des_processus(Parametre &p, std::index_sequence<Is...>) {
    	return { ((void)Is, Processus<T>{p})... };
    }
    
    template<typename T, size_t N>
    static std::array<Processus<T>, N> creer_des_processus(Parametre &p) {
    	return creer_des_processus(p, std::make_index_sequence<N>());
    }
    


    Malheureusement, mon compilateur (g++ 6.3.0 sur Debian 9, avec -std=c++14 -Wall -Wextra -Werror -pedantic) m’indique cette erreur :

    In file included from ~/main.cpp:9:
    ~/processus.hpp:43:2: note: declared here
      Processus(Processus const &) = delete;
      ^~~~~~~~~
    

    En sachant que Processus contient un constructeur par mouvement par défaut, déclaré de cette manière :

    Processus(Processus &&) = default;

    Je suis donc bloqué sans idée d’où aller, si quelqu’un a une solution (ou des pistes), je suis preneur.  Merci d’avance ! :)

    Édit :

    En fait j’ai réglé mon problème, un des membres de Processus n’était pas move-constructible, c’est corrigé (et mis en évidence par une version plus récente de gcc (en l’occurence, gcc 7 sur Gentoo) :

    ~/processus.hpp:46:5: note: « Processus<T>::Processus(Processus<T>&&) [avec T = short int] » est implicitement supprimé car la définition par défaut serait mal formée:
         Processus(Processus &&) = default;
         ^~~~~~~~~
    

    En indiquant juste en-dessous quelle est la (ou les) classes fautives.


    J’aurais une demande supplémentaire, si vous me le permettez : que signifie cette ligne (ou comment s’appelle cette technique) ?

    return { ((void)Is, Processus<T>{p})... };

    Pourquoi n’est-t’il pas possible d’écrire ceci :

    return { (Processus<T>{p})... };

    Merci à vous.


    -
    Edité par ouisicce 8 juillet 2019 à 22:10:19

    • Partager sur Facebook
    • Partager sur Twitter
      9 juillet 2019 à 11:40:32

      Bonjour,

      ici Is est le parameter pack, l'opérateur ... s'applique à lui.
      Dans le premier cas on va créer autant d'éléments qu'il y a d'éléments dans le tableau. Et comme en réalité les diverses valeurs pour Is (0, 1, 2, ... N) ne sont pas utilisées , on utilise l'opérateur virgule pour les ignorer.

      Le second cas n'a aucun sens. A quoi s’appliquerait l'opérateur ...?

      Je ne connais pas le nom de cette technique, que je découvre aujourd'hui.

      • Partager sur Facebook
      • Partager sur Twitter

      En recherche d'emploi.

      Initialisation d'un std::array<>

      × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
      × Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
      • Editeur
      • Markdown