来自参数包的C ++ 17 make_tuple

时间:2018-01-10 22:30:29

标签: c++ tuples metaprogramming c++17 template-meta-programming

我想做以下事情,但不知道为什么它没有用C ++ 17编译。

int func(int a) {
  // do some operations on a
  int res = operation_on_a(a);
  return res;
}

auto funcs(int... as) {
  return make_tuple(func(as)...);
}

auto v1 = func(1);
auto [v1, v2, v3] = funcs(1, 2, 3);  // Why this doesn't compile?

基本上,我们的想法是拥有一个名为func()的基函数,另一个函数采用可变参数将每个项应用于func()并返回std::tuple个结果。但是,除非我用模板类型替换int...,否则它不会被编译。在这种情况下,我知道参数都是整数。

1 个答案:

答案 0 :(得分:0)

  

我想做以下事情,但不知道为什么它没有用C ++ 17编译。

仅仅因为

auto funcs(int... as) {
  return make_tuple(func(as)...);
}

不是C ++语法。

我认为

template <typename Args>
auto funcs (Args ... as)
 { return std::make_tuple(func(as)...); }

考虑到每as...func()来电int,这是一个合理的解决方案。

但是如果你真的想要一些类似于变量函数的东西,它接受一个可变数量的int(如果你可以设置参数个数的上限),我建议采用以下解决方案。

首先,您需要一个接收类型和std::size_t的模板并返回该类型;

之类的东西
template <typename T, std::size_t>
using typer = T;

现在是一个带有自我继承的辅助递归struct

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)...); }
 };

定义bar struct s序列,static方法f接收一些int typer<int, Is> {{1} }})。

现在是int

struct foo

继承自template <std::size_t N = 64U> struct foo : public bar<std::make_index_sequence<N>> { }; bar的序列,并继承接收零,1,2,...,N-1 struct的{​​{1}}序列第

现在你可以打电话了

f()

因为在int auto [v1, v2, v3] = foo<>::f(1, 2, 3); 中还有一个foo方法,它只能接收三个struct个。

以下是一个完整的工作示例

f()