Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Multiple parameter packs -- how?

I have the following problem:

#include <vector>
#include <tuple>

using namespace std;

template< size_t... N_i, typename Ts... >
class A
{
  // ...

  private:
    std::vector<size_t> _v = { N_i... };
    std::tuple<Ts...> _t;
};

int main()
{
  A<1> a;
}

As you can see above, I try to define multiple parameter packs as template arguments of the class A.
Unfortunately, the code does not compile:

error: expected nested-name-specifier before 'Ts'

How can I define multiple parameter packs for this example?

like image 235
abraham_hilbert Avatar asked Oct 14 '16 21:10

abraham_hilbert


2 Answers

One way to achieve the end goal is by a using a nested template:

template< size_t... N_i> class initial_values {

public:

    template <typename Ts...>
    class A
    {
       // ...

       private:
         std::vector<size_t> _v = { N_i... };
         std::tuple<Ts...> _t;
    };
};

Then the template can be referenced as, for example:

initial_values<1,2,3>::A<int, char> a;
like image 65
Sam Varshavchik Avatar answered Oct 11 '22 09:10

Sam Varshavchik


Consider the error:

expected nested-name-specifier before 'Ts'

It is due to the fact that you wrote:

template< size_t... N_i, typename Ts... >

Instead of:

template< size_t... N_i, typename... Ts >

That said, even if you fix it, code won't compile.
This is because you can't mix two parameters packs the way you did.
You must refactor your code so as they can be deduced from the context somehow.

As an example, you can use std::index_sequence and a partial specialization as it follows:

#include <vector>
#include <tuple>
#include<functional>

using namespace std;

template< typename... >
class A;

template< size_t... N_i, typename... Ts >
class A<index_sequence<N_i...>, Ts...>
{
  // ...

  private:
    std::vector<size_t> _v = { N_i... };
    std::tuple<Ts...> _t;
};

int main()
{
  A<index_sequence<1>> a;
}
like image 38
skypjack Avatar answered Oct 11 '22 10:10

skypjack