I would like to do the following but didn't know why it didn't compile in C++17.
Simply because
auto funcs(int... as) {
return make_tuple(func(as)...);
}
isn't C++ syntax.
I think that
template <typename Args>
auto funcs (Args ... as)
{ return std::make_tuple(func(as)...); }
taking in count that every as...
call func()
that return an int
, is a reasonable solution.
But if you really want somethig that is like a variadic function that accept a variadic number of int
(and if you can set an upper limit for the number of arguments), I propose the following solution.
First of all, you need a template that receive a type and a std::size_t
and return the type; something like
template <typename T, std::size_t>
using typer = T;
Now an helper recursive struct
with self-inheritance
template <typename>
struct bar;
template <>
struct bar<std::index_sequence<>>
{
static void f () {}
};
template <std::size_t ... Is>
struct bar<std::index_sequence<Is...>>
: public bar<std::make_index_sequence<sizeof...(Is)-1U>>
{
using bar<std::make_index_sequence<sizeof...(Is)-1U>>::f;
static auto f (typer<int, Is>... as)
{ return std::make_tuple(func(as)...); }
};
that define a sequence of bar
struct
s with a static
method f
that receive some int
(typer<int, Is>
is int
).
Now a struct foo
template <std::size_t N = 64U>
struct foo : public bar<std::make_index_sequence<N>>
{ };
that inherit from a sequence of bar
struct
s and inherit a sequence of f()
that receive zero, 1, 2, ..., N-1 int
s.
Now you can call
auto [v1, v2, v3] = foo<>::f(1, 2, 3);
because in foo
struct
there is (also) a f()
method that receive exactly three int
s.
The following is a full working example
#include <tuple>
#include <iostream>
#include <type_traits>
int func(int a)
{ return a+1; }
template <typename T, std::size_t>
using typer = T;
template <typename>
struct bar;
template <>
struct bar<std::index_sequence<>>
{
static void f () {}
};
template <std::size_t ... Is>
struct bar<std::index_sequence<Is...>>
: public bar<std::make_index_sequence<sizeof...(Is)-1U>>
{
using bar<std::make_index_sequence<sizeof...(Is)-1U>>::f;
static auto f (typer<int, Is>... as)
{ return std::make_tuple(func(as)...); }
};
template <std::size_t N = 64U>
struct foo : public bar<std::make_index_sequence<N>>
{ };
int main ()
{
auto [v1, v2, v3] = foo<>::f(1, 2, 3);
std::cout << v1 << ", " << v2 << ", " << v3 << std::endl;
}