【问题标题】:C++17 make_tuple from an argument pack [duplicate]来自参数包的 C++17 make_tuple [重复]
【发布时间】:2018-06-20 04:45:49
【问题描述】:

我想做以下,但不知道为什么它没有在 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... 替换为模板类型,否则它不会被编译。在这种情况下,我知道参数都是整数。

【问题讨论】:

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


【解决方案1】:

我想做以下,但不知道为什么它没有在 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)...); }

考虑到每个返回intas... 调用func() 是一个合理的解决方案。

但如果你真的想要一个类似于可变参数的函数,它接受可变参数 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)...); }
 };

使用static 方法定义barstructs 的序列,f 接收一些inttyper&lt;int, Is&gt;int)。

现在是struct foo

template <std::size_t N = 64U>
struct foo : public bar<std::make_index_sequence<N>>
 { };

barstructs 的序列继承并继承f() 的序列,接收零、1、2、...、N-1 ints。

现在你可以打电话了

auto [v1, v2, v3] = foo<>::f(1, 2, 3);

因为在foo struct 中(也)有一个f() 方法可以接收三个ints。

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

#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;
 }

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-05-05
    • 2020-01-07
    • 2012-11-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-08-02
    相关资源
    最近更新 更多