unpacking values of an array as parameters to a variadic function












5















I am trying (at compile time) to unpack integers as arguments to a variadic function. The idea would be to have those values packed in an array or in a std::index_sequence (c++14) at compile time. I have tried to use some of the answers from older posts, but I find the example code unreadable for my level.



Here is a simple example with the functionality that I need to implement in a code that I am writing, in this case attempting to use std::make_index_sequence. I do not necessarily need to use the latter. The problem is that the values of the sequence are not unpacked as arguments to the variadic function:



#include <cstdio>
#include <iostream>
#include <utility>

using namespace std;


void print(const int &val){
cout << val << endl;
}

template<typename ...S> void print(const int &val, const S&... others)
{
print(val);
print(others...);
}

template<size_t n> void printNumbers(){
std::make_index_sequence<n> a;
print(a);
}


int main(){
printNumbers<6>();
}


The output from GCC8:



    tet.cc: In instantiation of ‘void printNumbers() [with long unsigned int n = 6]’:
tet.cc:25:19: required from here
tet.cc:20:8: error: no matching function for call to ‘print(std::make_index_sequence<6>&)’
print(a);
~~~~~^~~
tet.cc:8:6: note: candidate: ‘void print(const int&)’
void print(const int &val){
^~~~~
tet.cc:8:6: note: no known conversion for argument 1 from ‘std::make_index_sequence<6>’ {aka ‘std::integer_sequence<long unsigned int, 0, 1, 2, 3, 4, 5>’} to ‘const int&’
tet.cc:12:30: note: candidate: ‘template<class ... S> void print(const int&, const S& ...)’
template<typename ...S> void print(const int &val, const S&... others)
^~~~~
tet.cc:12:30: note: template argument deduction/substitution failed:
tet.cc:20:9: note: cannot convert ‘a’ (type ‘std::make_index_sequence<6>’ {aka ‘std::integer_sequence<long unsigned int, 0, 1, 2, 3, 4, 5>’}) to type ‘const int&’









share|improve this question





























    5















    I am trying (at compile time) to unpack integers as arguments to a variadic function. The idea would be to have those values packed in an array or in a std::index_sequence (c++14) at compile time. I have tried to use some of the answers from older posts, but I find the example code unreadable for my level.



    Here is a simple example with the functionality that I need to implement in a code that I am writing, in this case attempting to use std::make_index_sequence. I do not necessarily need to use the latter. The problem is that the values of the sequence are not unpacked as arguments to the variadic function:



    #include <cstdio>
    #include <iostream>
    #include <utility>

    using namespace std;


    void print(const int &val){
    cout << val << endl;
    }

    template<typename ...S> void print(const int &val, const S&... others)
    {
    print(val);
    print(others...);
    }

    template<size_t n> void printNumbers(){
    std::make_index_sequence<n> a;
    print(a);
    }


    int main(){
    printNumbers<6>();
    }


    The output from GCC8:



        tet.cc: In instantiation of ‘void printNumbers() [with long unsigned int n = 6]’:
    tet.cc:25:19: required from here
    tet.cc:20:8: error: no matching function for call to ‘print(std::make_index_sequence<6>&)’
    print(a);
    ~~~~~^~~
    tet.cc:8:6: note: candidate: ‘void print(const int&)’
    void print(const int &val){
    ^~~~~
    tet.cc:8:6: note: no known conversion for argument 1 from ‘std::make_index_sequence<6>’ {aka ‘std::integer_sequence<long unsigned int, 0, 1, 2, 3, 4, 5>’} to ‘const int&’
    tet.cc:12:30: note: candidate: ‘template<class ... S> void print(const int&, const S& ...)’
    template<typename ...S> void print(const int &val, const S&... others)
    ^~~~~
    tet.cc:12:30: note: template argument deduction/substitution failed:
    tet.cc:20:9: note: cannot convert ‘a’ (type ‘std::make_index_sequence<6>’ {aka ‘std::integer_sequence<long unsigned int, 0, 1, 2, 3, 4, 5>’}) to type ‘const int&’









    share|improve this question



























      5












      5








      5








      I am trying (at compile time) to unpack integers as arguments to a variadic function. The idea would be to have those values packed in an array or in a std::index_sequence (c++14) at compile time. I have tried to use some of the answers from older posts, but I find the example code unreadable for my level.



      Here is a simple example with the functionality that I need to implement in a code that I am writing, in this case attempting to use std::make_index_sequence. I do not necessarily need to use the latter. The problem is that the values of the sequence are not unpacked as arguments to the variadic function:



      #include <cstdio>
      #include <iostream>
      #include <utility>

      using namespace std;


      void print(const int &val){
      cout << val << endl;
      }

      template<typename ...S> void print(const int &val, const S&... others)
      {
      print(val);
      print(others...);
      }

      template<size_t n> void printNumbers(){
      std::make_index_sequence<n> a;
      print(a);
      }


      int main(){
      printNumbers<6>();
      }


      The output from GCC8:



          tet.cc: In instantiation of ‘void printNumbers() [with long unsigned int n = 6]’:
      tet.cc:25:19: required from here
      tet.cc:20:8: error: no matching function for call to ‘print(std::make_index_sequence<6>&)’
      print(a);
      ~~~~~^~~
      tet.cc:8:6: note: candidate: ‘void print(const int&)’
      void print(const int &val){
      ^~~~~
      tet.cc:8:6: note: no known conversion for argument 1 from ‘std::make_index_sequence<6>’ {aka ‘std::integer_sequence<long unsigned int, 0, 1, 2, 3, 4, 5>’} to ‘const int&’
      tet.cc:12:30: note: candidate: ‘template<class ... S> void print(const int&, const S& ...)’
      template<typename ...S> void print(const int &val, const S&... others)
      ^~~~~
      tet.cc:12:30: note: template argument deduction/substitution failed:
      tet.cc:20:9: note: cannot convert ‘a’ (type ‘std::make_index_sequence<6>’ {aka ‘std::integer_sequence<long unsigned int, 0, 1, 2, 3, 4, 5>’}) to type ‘const int&’









      share|improve this question
















      I am trying (at compile time) to unpack integers as arguments to a variadic function. The idea would be to have those values packed in an array or in a std::index_sequence (c++14) at compile time. I have tried to use some of the answers from older posts, but I find the example code unreadable for my level.



      Here is a simple example with the functionality that I need to implement in a code that I am writing, in this case attempting to use std::make_index_sequence. I do not necessarily need to use the latter. The problem is that the values of the sequence are not unpacked as arguments to the variadic function:



      #include <cstdio>
      #include <iostream>
      #include <utility>

      using namespace std;


      void print(const int &val){
      cout << val << endl;
      }

      template<typename ...S> void print(const int &val, const S&... others)
      {
      print(val);
      print(others...);
      }

      template<size_t n> void printNumbers(){
      std::make_index_sequence<n> a;
      print(a);
      }


      int main(){
      printNumbers<6>();
      }


      The output from GCC8:



          tet.cc: In instantiation of ‘void printNumbers() [with long unsigned int n = 6]’:
      tet.cc:25:19: required from here
      tet.cc:20:8: error: no matching function for call to ‘print(std::make_index_sequence<6>&)’
      print(a);
      ~~~~~^~~
      tet.cc:8:6: note: candidate: ‘void print(const int&)’
      void print(const int &val){
      ^~~~~
      tet.cc:8:6: note: no known conversion for argument 1 from ‘std::make_index_sequence<6>’ {aka ‘std::integer_sequence<long unsigned int, 0, 1, 2, 3, 4, 5>’} to ‘const int&’
      tet.cc:12:30: note: candidate: ‘template<class ... S> void print(const int&, const S& ...)’
      template<typename ...S> void print(const int &val, const S&... others)
      ^~~~~
      tet.cc:12:30: note: template argument deduction/substitution failed:
      tet.cc:20:9: note: cannot convert ‘a’ (type ‘std::make_index_sequence<6>’ {aka ‘std::integer_sequence<long unsigned int, 0, 1, 2, 3, 4, 5>’}) to type ‘const int&’






      c++ c++11 c++14 variadic-templates template-meta-programming






      share|improve this question















      share|improve this question













      share|improve this question




      share|improve this question








      edited Nov 24 '18 at 11:08









      max66

      36.5k74165




      36.5k74165










      asked Nov 24 '18 at 9:03









      JdlCRJdlCR

      454




      454
























          2 Answers
          2






          active

          oldest

          votes


















          4














          std::make_index_sequence<6> is an alias for:



          std::integer_sequence<std::size_t, 0, 1, 2, 3, 4, 5>


          and this is the type of the expression a that is the argument of the function call print(a). Your print function expects individual values, not an std::integer_sequence.



          To make your implementation work, you should first deduce the indices, and only then use them as arguments for print:



          template <std::size_t... Is>
          void printNumbers(std::index_sequence<Is...>)
          {
          print(Is...);
          }

          template <std::size_t N>
          void printNumbers()
          {
          printNumbers(std::make_index_sequence<N>{});
          }


          In c++17 you could remove the intermediate print function and just say:



          template <std::size_t... Is>
          void printNumbers(std::index_sequence<Is...>)
          {
          (print(Is), ...);
          }


          In c++20 you can both create an index sequence and deduce its indices within a single function:



          template <std::size_t N>
          void printNumbers()
          {
          <std::size_t... Is> (std::index_sequence<Is...>)
          { (print(Is), ...); }(std::make_index_sequence<N>{});
          }


          DEMO






          share|improve this answer

































            1














            As an addendum to the Piotr Skotnicki's answer, I propose a C++14 way to avoid the recursive print().



            Not so elegant as the C++17 solution, based on template folding, but equally permit to avoid the use of recursion (and consider that template recursion is usually strict limited by compilers, so the recursive solution works but not when N exceed the recursion limit).



            You have to write the printNumber() function as usual, passing a std::make_index_sequence<N> (that inherit from std::index_sequence<0, 1, ...., N-1> aka std::integer_sequence<std::size_t, 0, 1, ..., N-1>) to another function



            template <std::size_t N>
            void printNumbers ()
            { printNumbers2(std::make_index_sequence<N>{}); }


            but in the printNumbers2() you can avoid to call the recursive print() and you can call the print() that effectively call std::cout inside the initialization of an unused array



            template <std::size_t ... Is>
            void printNumbers2 (std::index_sequence<Is...>)
            {
            using unused = int;

            (void)unused { 0, (print(Is), 0)... };
            }


            You can also avoid both print() functions printing directly in printNumbers2()



            void printNumbers2 (std::index_sequence<Is...>)
            {
            using unused = int;

            (void)unused { 0, (std::cout << val << std::endl, 0)... };
            }


            You can do the same in the C++17/C++20 template folding solutions.



            In C++11 this solution doesn't works but only because std::make_integer_sequence and std::index_sequence are introduced from C++11.



            If you write a C++11 surrogate for std::make_integer_sequence and std::index_sequence, you can adapt this solution also to C++11.






            share|improve this answer























              Your Answer






              StackExchange.ifUsing("editor", function () {
              StackExchange.using("externalEditor", function () {
              StackExchange.using("snippets", function () {
              StackExchange.snippets.init();
              });
              });
              }, "code-snippets");

              StackExchange.ready(function() {
              var channelOptions = {
              tags: "".split(" "),
              id: "1"
              };
              initTagRenderer("".split(" "), "".split(" "), channelOptions);

              StackExchange.using("externalEditor", function() {
              // Have to fire editor after snippets, if snippets enabled
              if (StackExchange.settings.snippets.snippetsEnabled) {
              StackExchange.using("snippets", function() {
              createEditor();
              });
              }
              else {
              createEditor();
              }
              });

              function createEditor() {
              StackExchange.prepareEditor({
              heartbeatType: 'answer',
              autoActivateHeartbeat: false,
              convertImagesToLinks: true,
              noModals: true,
              showLowRepImageUploadWarning: true,
              reputationToPostImages: 10,
              bindNavPrevention: true,
              postfix: "",
              imageUploader: {
              brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
              contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
              allowUrls: true
              },
              onDemand: true,
              discardSelector: ".discard-answer"
              ,immediatelyShowMarkdownHelp:true
              });


              }
              });














              draft saved

              draft discarded


















              StackExchange.ready(
              function () {
              StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53456688%2funpacking-values-of-an-array-as-parameters-to-a-variadic-function%23new-answer', 'question_page');
              }
              );

              Post as a guest















              Required, but never shown

























              2 Answers
              2






              active

              oldest

              votes








              2 Answers
              2






              active

              oldest

              votes









              active

              oldest

              votes






              active

              oldest

              votes









              4














              std::make_index_sequence<6> is an alias for:



              std::integer_sequence<std::size_t, 0, 1, 2, 3, 4, 5>


              and this is the type of the expression a that is the argument of the function call print(a). Your print function expects individual values, not an std::integer_sequence.



              To make your implementation work, you should first deduce the indices, and only then use them as arguments for print:



              template <std::size_t... Is>
              void printNumbers(std::index_sequence<Is...>)
              {
              print(Is...);
              }

              template <std::size_t N>
              void printNumbers()
              {
              printNumbers(std::make_index_sequence<N>{});
              }


              In c++17 you could remove the intermediate print function and just say:



              template <std::size_t... Is>
              void printNumbers(std::index_sequence<Is...>)
              {
              (print(Is), ...);
              }


              In c++20 you can both create an index sequence and deduce its indices within a single function:



              template <std::size_t N>
              void printNumbers()
              {
              <std::size_t... Is> (std::index_sequence<Is...>)
              { (print(Is), ...); }(std::make_index_sequence<N>{});
              }


              DEMO






              share|improve this answer






























                4














                std::make_index_sequence<6> is an alias for:



                std::integer_sequence<std::size_t, 0, 1, 2, 3, 4, 5>


                and this is the type of the expression a that is the argument of the function call print(a). Your print function expects individual values, not an std::integer_sequence.



                To make your implementation work, you should first deduce the indices, and only then use them as arguments for print:



                template <std::size_t... Is>
                void printNumbers(std::index_sequence<Is...>)
                {
                print(Is...);
                }

                template <std::size_t N>
                void printNumbers()
                {
                printNumbers(std::make_index_sequence<N>{});
                }


                In c++17 you could remove the intermediate print function and just say:



                template <std::size_t... Is>
                void printNumbers(std::index_sequence<Is...>)
                {
                (print(Is), ...);
                }


                In c++20 you can both create an index sequence and deduce its indices within a single function:



                template <std::size_t N>
                void printNumbers()
                {
                <std::size_t... Is> (std::index_sequence<Is...>)
                { (print(Is), ...); }(std::make_index_sequence<N>{});
                }


                DEMO






                share|improve this answer




























                  4












                  4








                  4







                  std::make_index_sequence<6> is an alias for:



                  std::integer_sequence<std::size_t, 0, 1, 2, 3, 4, 5>


                  and this is the type of the expression a that is the argument of the function call print(a). Your print function expects individual values, not an std::integer_sequence.



                  To make your implementation work, you should first deduce the indices, and only then use them as arguments for print:



                  template <std::size_t... Is>
                  void printNumbers(std::index_sequence<Is...>)
                  {
                  print(Is...);
                  }

                  template <std::size_t N>
                  void printNumbers()
                  {
                  printNumbers(std::make_index_sequence<N>{});
                  }


                  In c++17 you could remove the intermediate print function and just say:



                  template <std::size_t... Is>
                  void printNumbers(std::index_sequence<Is...>)
                  {
                  (print(Is), ...);
                  }


                  In c++20 you can both create an index sequence and deduce its indices within a single function:



                  template <std::size_t N>
                  void printNumbers()
                  {
                  <std::size_t... Is> (std::index_sequence<Is...>)
                  { (print(Is), ...); }(std::make_index_sequence<N>{});
                  }


                  DEMO






                  share|improve this answer















                  std::make_index_sequence<6> is an alias for:



                  std::integer_sequence<std::size_t, 0, 1, 2, 3, 4, 5>


                  and this is the type of the expression a that is the argument of the function call print(a). Your print function expects individual values, not an std::integer_sequence.



                  To make your implementation work, you should first deduce the indices, and only then use them as arguments for print:



                  template <std::size_t... Is>
                  void printNumbers(std::index_sequence<Is...>)
                  {
                  print(Is...);
                  }

                  template <std::size_t N>
                  void printNumbers()
                  {
                  printNumbers(std::make_index_sequence<N>{});
                  }


                  In c++17 you could remove the intermediate print function and just say:



                  template <std::size_t... Is>
                  void printNumbers(std::index_sequence<Is...>)
                  {
                  (print(Is), ...);
                  }


                  In c++20 you can both create an index sequence and deduce its indices within a single function:



                  template <std::size_t N>
                  void printNumbers()
                  {
                  <std::size_t... Is> (std::index_sequence<Is...>)
                  { (print(Is), ...); }(std::make_index_sequence<N>{});
                  }


                  DEMO







                  share|improve this answer














                  share|improve this answer



                  share|improve this answer








                  edited Nov 24 '18 at 10:04

























                  answered Nov 24 '18 at 9:12









                  Piotr SkotnickiPiotr Skotnicki

                  34.8k472118




                  34.8k472118

























                      1














                      As an addendum to the Piotr Skotnicki's answer, I propose a C++14 way to avoid the recursive print().



                      Not so elegant as the C++17 solution, based on template folding, but equally permit to avoid the use of recursion (and consider that template recursion is usually strict limited by compilers, so the recursive solution works but not when N exceed the recursion limit).



                      You have to write the printNumber() function as usual, passing a std::make_index_sequence<N> (that inherit from std::index_sequence<0, 1, ...., N-1> aka std::integer_sequence<std::size_t, 0, 1, ..., N-1>) to another function



                      template <std::size_t N>
                      void printNumbers ()
                      { printNumbers2(std::make_index_sequence<N>{}); }


                      but in the printNumbers2() you can avoid to call the recursive print() and you can call the print() that effectively call std::cout inside the initialization of an unused array



                      template <std::size_t ... Is>
                      void printNumbers2 (std::index_sequence<Is...>)
                      {
                      using unused = int;

                      (void)unused { 0, (print(Is), 0)... };
                      }


                      You can also avoid both print() functions printing directly in printNumbers2()



                      void printNumbers2 (std::index_sequence<Is...>)
                      {
                      using unused = int;

                      (void)unused { 0, (std::cout << val << std::endl, 0)... };
                      }


                      You can do the same in the C++17/C++20 template folding solutions.



                      In C++11 this solution doesn't works but only because std::make_integer_sequence and std::index_sequence are introduced from C++11.



                      If you write a C++11 surrogate for std::make_integer_sequence and std::index_sequence, you can adapt this solution also to C++11.






                      share|improve this answer




























                        1














                        As an addendum to the Piotr Skotnicki's answer, I propose a C++14 way to avoid the recursive print().



                        Not so elegant as the C++17 solution, based on template folding, but equally permit to avoid the use of recursion (and consider that template recursion is usually strict limited by compilers, so the recursive solution works but not when N exceed the recursion limit).



                        You have to write the printNumber() function as usual, passing a std::make_index_sequence<N> (that inherit from std::index_sequence<0, 1, ...., N-1> aka std::integer_sequence<std::size_t, 0, 1, ..., N-1>) to another function



                        template <std::size_t N>
                        void printNumbers ()
                        { printNumbers2(std::make_index_sequence<N>{}); }


                        but in the printNumbers2() you can avoid to call the recursive print() and you can call the print() that effectively call std::cout inside the initialization of an unused array



                        template <std::size_t ... Is>
                        void printNumbers2 (std::index_sequence<Is...>)
                        {
                        using unused = int;

                        (void)unused { 0, (print(Is), 0)... };
                        }


                        You can also avoid both print() functions printing directly in printNumbers2()



                        void printNumbers2 (std::index_sequence<Is...>)
                        {
                        using unused = int;

                        (void)unused { 0, (std::cout << val << std::endl, 0)... };
                        }


                        You can do the same in the C++17/C++20 template folding solutions.



                        In C++11 this solution doesn't works but only because std::make_integer_sequence and std::index_sequence are introduced from C++11.



                        If you write a C++11 surrogate for std::make_integer_sequence and std::index_sequence, you can adapt this solution also to C++11.






                        share|improve this answer


























                          1












                          1








                          1







                          As an addendum to the Piotr Skotnicki's answer, I propose a C++14 way to avoid the recursive print().



                          Not so elegant as the C++17 solution, based on template folding, but equally permit to avoid the use of recursion (and consider that template recursion is usually strict limited by compilers, so the recursive solution works but not when N exceed the recursion limit).



                          You have to write the printNumber() function as usual, passing a std::make_index_sequence<N> (that inherit from std::index_sequence<0, 1, ...., N-1> aka std::integer_sequence<std::size_t, 0, 1, ..., N-1>) to another function



                          template <std::size_t N>
                          void printNumbers ()
                          { printNumbers2(std::make_index_sequence<N>{}); }


                          but in the printNumbers2() you can avoid to call the recursive print() and you can call the print() that effectively call std::cout inside the initialization of an unused array



                          template <std::size_t ... Is>
                          void printNumbers2 (std::index_sequence<Is...>)
                          {
                          using unused = int;

                          (void)unused { 0, (print(Is), 0)... };
                          }


                          You can also avoid both print() functions printing directly in printNumbers2()



                          void printNumbers2 (std::index_sequence<Is...>)
                          {
                          using unused = int;

                          (void)unused { 0, (std::cout << val << std::endl, 0)... };
                          }


                          You can do the same in the C++17/C++20 template folding solutions.



                          In C++11 this solution doesn't works but only because std::make_integer_sequence and std::index_sequence are introduced from C++11.



                          If you write a C++11 surrogate for std::make_integer_sequence and std::index_sequence, you can adapt this solution also to C++11.






                          share|improve this answer













                          As an addendum to the Piotr Skotnicki's answer, I propose a C++14 way to avoid the recursive print().



                          Not so elegant as the C++17 solution, based on template folding, but equally permit to avoid the use of recursion (and consider that template recursion is usually strict limited by compilers, so the recursive solution works but not when N exceed the recursion limit).



                          You have to write the printNumber() function as usual, passing a std::make_index_sequence<N> (that inherit from std::index_sequence<0, 1, ...., N-1> aka std::integer_sequence<std::size_t, 0, 1, ..., N-1>) to another function



                          template <std::size_t N>
                          void printNumbers ()
                          { printNumbers2(std::make_index_sequence<N>{}); }


                          but in the printNumbers2() you can avoid to call the recursive print() and you can call the print() that effectively call std::cout inside the initialization of an unused array



                          template <std::size_t ... Is>
                          void printNumbers2 (std::index_sequence<Is...>)
                          {
                          using unused = int;

                          (void)unused { 0, (print(Is), 0)... };
                          }


                          You can also avoid both print() functions printing directly in printNumbers2()



                          void printNumbers2 (std::index_sequence<Is...>)
                          {
                          using unused = int;

                          (void)unused { 0, (std::cout << val << std::endl, 0)... };
                          }


                          You can do the same in the C++17/C++20 template folding solutions.



                          In C++11 this solution doesn't works but only because std::make_integer_sequence and std::index_sequence are introduced from C++11.



                          If you write a C++11 surrogate for std::make_integer_sequence and std::index_sequence, you can adapt this solution also to C++11.







                          share|improve this answer












                          share|improve this answer



                          share|improve this answer










                          answered Nov 24 '18 at 10:46









                          max66max66

                          36.5k74165




                          36.5k74165






























                              draft saved

                              draft discarded




















































                              Thanks for contributing an answer to Stack Overflow!


                              • Please be sure to answer the question. Provide details and share your research!

                              But avoid



                              • Asking for help, clarification, or responding to other answers.

                              • Making statements based on opinion; back them up with references or personal experience.


                              To learn more, see our tips on writing great answers.




                              draft saved


                              draft discarded














                              StackExchange.ready(
                              function () {
                              StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53456688%2funpacking-values-of-an-array-as-parameters-to-a-variadic-function%23new-answer', 'question_page');
                              }
                              );

                              Post as a guest















                              Required, but never shown





















































                              Required, but never shown














                              Required, but never shown












                              Required, but never shown







                              Required, but never shown

































                              Required, but never shown














                              Required, but never shown












                              Required, but never shown







                              Required, but never shown







                              Popular posts from this blog

                              404 Error Contact Form 7 ajax form submitting

                              How to know if a Active Directory user can login interactively

                              TypeError: fit_transform() missing 1 required positional argument: 'X'