Partage
  • Partager sur Facebook
  • Partager sur Twitter

Prototype de fonction 'infini'

c++ ;)

Sujet résolu
    17 mars 2018 à 19:49:49

    Bonjour, je voudrais créer une fonction avec des paramètres 'infini' en gros un truc comme ça :

    int additionGeniale(int aa,int ab, int ac,........,int zz);

    qui puisse prendre tout les surcharge de ce type par exemple :

    additionGeniale(1 ,2 ); // ==3
    additionGeniale(4, 5, -3); //==6
    
    

    Histoire de ne pas écrire 60 fonctions additionGeniale en ce disant que ça suffit ;)

    Si quelqu'un a déjà coder un truc comme ça, donner un exemple ou bien une explication serai simpa.

    Merci a vous !


    -
    Edité par Golgoo 17 mars 2018 à 19:50:01

    • Partager sur Facebook
    • Partager sur Twitter
      17 mars 2018 à 20:22:18

      passe un vecteur d'int.
      • Partager sur Facebook
      • Partager sur Twitter
        17 mars 2018 à 21:57:43

        Il faut que tu te renseignes sur les variadic template si tu cherches à rester sur cette idée d'infinité de paramètres.

        Par contre c'est assez complexe et tu peux essayer de passer par des itérateurs sinon, ça serait plus simple à coder !

        Et si ta fonction est une simple accumulation, std::accumulate devrait t'intéresser !

        -
        Edité par zeFresk 18 mars 2018 à 1:27:35

        • Partager sur Facebook
        • Partager sur Twitter
        La flemme vaincra.
          17 mars 2018 à 23:31:19

          Entre autre c'est accumulation, le truc c'est que je veux le faire en liant des classe SDL entre elle, ( un peu plus compliqué que additionGeniale ;) )

          ça marche si l'argument est seul, ou bien s'il y en a 2. ( le 2nd devient dépendant du premier et le 1er du second en gros ).

          mais si je veux en mettre 3 dépendant entre eux : je doit d'abord mettre le 1er dépendant avec le 2nd puis le 2nd avec le 3ème ( ou bien le 1er avec le 3ème ) pour qu'il soit tout les trois dépendant.

          En gros faudrait appeler récursivement cette fonction avec le 1er arg et le 2ème , puis le 1er et le troisième, puis le 1er et le 4ème jusqu'à ce qu'il n'y est plus d'argument ( ou bien 1er / 2 eme , 2eme / 3eme , etc..).

          Merci pour votre aide, mais avant de me lancer dans une longue longue... recherche, j'aimerai bien savoir ce qui correspond le mieux :)

          donc pour l'instant on hésite entre : std::accumulate / variadic template / et itérateurs c'est bien ça ?

          -
          Edité par Golgoo 17 mars 2018 à 23:33:10

          • Partager sur Facebook
          • Partager sur Twitter
            18 mars 2018 à 1:00:48

            lu',

            il y'a eu un lien genial recemment. Je crois qu'on est en plein dans la phase 3.

            • Partager sur Facebook
            • Partager sur Twitter

            Eug

              18 mars 2018 à 1:15:31

              Haha , non si on règle le problème pour X ou pour Y, ça me règle le problème ;) un truc dans ce genre sinon : Somme((int[]){val1,val2,val3});

              Mais pour avoir la taille Vector est pas mal, aux moins ça règle mon problème Y. Mais oui il y a le problème X xD

              qui veux que mes classe soit utilisable le plus simplement possible, donc pouvoir appeler cette fonctions sans parler de vecteur ( le plus simple d'utilisation pour un utilisateur lambda );

              En effet va_list règle le problème sans soucis sujet résolut gracias

              -
              Edité par Golgoo 18 mars 2018 à 2:04:58

              • Partager sur Facebook
              • Partager sur Twitter
                18 mars 2018 à 2:12:24

                va_list et consort c'est pour le C. En C++, il y'a les variadics

                • Partager sur Facebook
                • Partager sur Twitter

                Eug

                  18 mars 2018 à 2:39:37

                  Ca à l'air plus complexe a s'approprier quand même, en tout cas va_list règle mon pb facilement, et pour apprendre à s'en servir : http://codes-sources.commentcamarche.net/faq/877-les-fonctions-a-nombre-variable-d-arguments

                  c'est assez simple :)

                  Je t'avoue qu'a première vu, j'ai du mal a bien comprendre, ça à l'air d'être utile si on ne connais pas le type des arguments non définis en tout cas.


                  void handler::addLinkedAnim(int animIndexMaster,int animIndexSlave, int animIndexSlave2, ...) { if (animIndexMaster < 0 || animIndexMaster > _nbreAnim) { std::cout << "Index MasterAnim innaproprie addLinkedAnim" << animIndexMaster << std::endl; return; } int linkedIndex = _hAnimation[animIndexMaster].getLinkGrade(); if (linkedIndex < 0) { addLinkedAnim(animIndexMaster); } va_list start; va_start(start, animIndexMaster); int indexRead = va_arg(start,int); while (indexRead >= 0) { addLinkedAnim(animIndexMaster, indexRead); indexRead = va_arg(start, int); } va_end(start); }

                  -
                  Edité par Golgoo 18 mars 2018 à 2:40:01

                  • Partager sur Facebook
                  • Partager sur Twitter
                    18 mars 2018 à 4:32:45

                    Le problème avec les itérateurs de la STL, c'est qu'il n'y a pas d'itérateur sur un groupement de valeur. Et faire des groupes avec des templates variadiques est extrêmement complexe si on ne possède pas de connaissance en méta-prog.

                    Avec range v3:

                    #define RANGES_NO_STD_FORWARD_DECLARATIONS
                    #include <range/v3/algorithm/for_each.hpp>
                    #include <range/v3/view/chunk.hpp>
                    #include <range/v3/view/iota.hpp>
                    
                    #include <iostream>
                    #include <string>
                    
                    int main()
                    {
                      std::string s;
                      auto container = ranges::view::ints(0, 10);
                      ranges::for_each(container | ranges::view::chunk(3), [&s](auto rng){
                        s += '{';
                        ranges::for_each(rng, [&s](int i){ s += std::to_string(i); });
                        s += '}';
                      });
                      std::cout << s;
                    }
                    {012}{345}{678}{9}
                    

                    Avec fold expression.

                    #include <iostream>
                    #include <utility>
                    #include <string>
                    
                    namespace detail
                    {
                      template<std::size_t, class T>
                      struct indexed_element
                      {
                        T& value;
                      };
                    
                      template<std::size_t i, class T>
                      T&& get(indexed_element<i, T>& x)
                      {
                        return static_cast<T&&>(x.value);
                      }
                    
                      template<class Ints, class... Ts>
                      struct tuple;
                    
                      template<std::size_t... Ints, class... Ts>
                      struct tuple<std::index_sequence<Ints...>, Ts...>
                        : indexed_element<Ints, Ts>...
                      {};
                    
                      template<class... Ts>
                      auto make_tuple(Ts&&... xs) noexcept
                      {
                        return tuple<std::make_index_sequence<sizeof...(Ts)>, Ts&&...>{{xs}...};
                      }
                    }
                    
                    template<std::size_t... Nths, std::size_t... Ints, class F, class Tuple>
                    void apply_n_impl(std::index_sequence<Nths...>, std::index_sequence<Ints...>, F& f, Tuple t)
                    {
                      auto g = [&](auto i){ f(detail::get<Nths+i>(t)...); };
                      (g(std::integral_constant<std::size_t, Ints>{}), ...);
                    }
                    
                    template<std::size_t... Nths, class I, class F, class Tuple>
                    void apply_i_impl(std::index_sequence<Nths...>, I i, F& f, Tuple t)
                    {
                      f(detail::get<Nths+i>(t)...);
                    }
                    
                    template<std::size_t arity, class F, class... Args>
                    void apply_n(F&& f, Args&&... args)
                    {
                      auto t = detail::make_tuple(static_cast<Args&&>(args)...);
                      apply_n_impl(
                        std::make_index_sequence<arity>{},
                        std::make_index_sequence<sizeof...(Args) / arity>{},
                        f, t
                      );
                      if constexpr (sizeof...(Args) % arity) {
                        apply_i_impl(
                          std::make_index_sequence<sizeof...(Args) % arity>{},
                          std::integral_constant<std::size_t, sizeof...(Args) / arity * arity>{},
                          f, t
                        );
                      }
                    }
                    
                    int main()
                    {
                      std::string s;
                      auto append_to_s = [&s](auto&&... xs) {
                        s += '{' ;
                        (s += ... += std::to_string(xs));
                        s += '}';
                      };
                      apply_n<3>(append_to_s, 0,1,2,3,4,5,6,7,8,9);
                      std::cout << s;
                    }
                    {012}{345}{678}{9}
                    

                    -
                    Edité par jo_link_noir 18 mars 2018 à 4:35:56

                    • Partager sur Facebook
                    • Partager sur Twitter
                      19 mars 2018 à 15:24:36

                      pourquoi s'embeter a créer une telle fonction, en c++ tu a la surcharge de l'opérateur + en programmation orientée object cf le cours d'openclassroom qui explique cela bien (même si certain points sont dépréciés par la communauté mais je ne connais pas d'autres cours de c++ complet hormis le cours de gbdivers qui n'est pas encore fini)
                      • Partager sur Facebook
                      • Partager sur Twitter
                      un projet ? Fait le ou ne le fait pas, il n'y a pas d'essai.
                        19 mars 2018 à 15:39:56

                        A R K a écrit:

                        (même si certain points sont dépréciés par la communauté

                        Pour ainsi dire : tout.

                        A R K a écrit:

                        mais je ne connais pas d'autres cours de c++ complet hormis le cours de gbdivers qui n'est pas encore fini)

                        C++ Primer 5th Edition. (Et avant le "oui mais c'est en anglais" : l'anglais est vital en programmation).

                        • Partager sur Facebook
                        • Partager sur Twitter

                        Posez vos questions ou discutez informatique, sur le Discord NaN | Tuto : Preuve de programmes C

                          19 mars 2018 à 16:46:39

                          Oublie les variadics du C, c'est une catastrophe -- car il faudra aussi passer le nombre d'éléments et prier que tu ne t'es pas trompé dans les paramètres passés. Choisis plutôt entre:

                          - std::vector -- le plus simple

                          - les variadic templates du C++ -- qui n'a d'intérêt que pour des cas vraiment connus à la compilation

                          - les initialiser-list -- le second plus simple, mais surprenant en syntaxe

                          • Partager sur Facebook
                          • Partager sur Twitter
                          C++: Blog|FAQ C++ dvpz|FAQ fclc++|FAQ Comeau|FAQ C++lite|FAQ BS| Bons livres sur le C++| PS: Je ne réponds pas aux questions techniques par MP.
                            19 mars 2018 à 19:58:27

                            Je n'avais pas vu les derniers messages avant de poster. Du coup je me rends compte de n'avoir absolument pas comprit cette histoire de dépendance.

                            Je suppose que la condition "indexRead >= 0" sur le dernier paramètre qui doit alors être 0 ? Avec des variadiques template, le code avec des va_* serait simplement: (addLinkedAnim(animIndexMaster, indexRead), ...); sans besoin de mettre un zéro terminal.

                            @lmghs: J'ai du mal à voir où se situe la surprise avec initializer_list ?

                            -
                            Edité par jo_link_noir 19 mars 2018 à 19:58:41

                            • Partager sur Facebook
                            • Partager sur Twitter
                              19 mars 2018 à 23:56:33

                              @jo_link_noir, c'est dans les accolades supplémentaires, mais nécessaires, qui peuvent surprendre l'utilisateur qui voudrait passer ses paramètres directement.

                              -
                              Edité par lmghs 19 mars 2018 à 23:56:56

                              • Partager sur Facebook
                              • Partager sur Twitter
                              C++: Blog|FAQ C++ dvpz|FAQ fclc++|FAQ Comeau|FAQ C++lite|FAQ BS| Bons livres sur le C++| PS: Je ne réponds pas aux questions techniques par MP.

                              Prototype de fonction 'infini'

                              × 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