c++ - 嵌套参数包扩展失败

标签 c++ c++14

我正在尝试编写一个作为输入的转换函数

  • 一个仿函数,这些参数的数量与输入的数量相同tuple s。
  • 任意数量的tuple小号

  • 并输出转换后的 tuple .

    我们假设输入元组具有相同的类型。

    例如,下面的代码片段应该对元组执行加法运算,得到 tuple{5, 7, 9} .

     auto t = transform(
                         [](auto i, auto j) {
                           return i + j;
                         },
                         std::make_tuple(1, 2, 3), 
                         std::make_tuple(4, 5, 6));
    

    代码 :

    #include <tuple>
    #include <type_traits>
    
    #include <iostream>
    
    template <size_t idx, typename... Ts>
    using get_nth_type = std::tuple_element_t<idx, std::tuple<Ts...>>;
    
    template <typename Func, size_t... indices, typename... Ts>
    auto transform(Func f, std::index_sequence<indices...>, Ts&&... input) {
      return std::make_tuple(f(std::get<indices>(std::forward<Ts>(input))...)...);
    }
    
    template <typename Func, typename... Ts>
    auto transform(Func f, Ts&&... input) {
      return transform(f, std::make_index_sequence<std::tuple_size<get_nth_type<0, Ts...>>::value>(),
                       std::forward<Ts>(input)...);
    }
    
    int main() {
      auto t = transform(
                         [](auto i, auto j) {
                           std::cout << i + j << '\n';
                           return -i;
                         },
                         std::make_tuple(1, 2, 3), std::make_tuple(4, 5, 6));
      // Desired output: 5
      //                 7
      //                 9
      std::cout << std::get<0>(t) << ", " << std::get<1>(t) << ", " << std::get<2>(t);
      // Desired output: -1
      //                 -2
      //                 -3
    }
    

    错误信息 :
    error: pack expansion does not contain any unexpanded parameter packs
      return std::make_tuple(f(std::get<indices>(std::forward<Ts>(inputs))...)...);
                             ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^
    

    似乎 indicesinput以错误的顺序展开。但我无法弄清楚正确的方法是什么。

    Try it here

    最佳答案

    问题是你想要 Ts/input由第一个包扩展和 indices 扩展的包由第二个包扩展包,但都 indicesTs/input作为第一个包扩展的操作数的一部分出现,因此它们与第一个扩展并行扩展,不为第二个扩展留下任何东西。

    您可以通过在另一个函数调用内部进行第一次扩展并在其外部进行第二次扩展来避免这种情况:

    template <std::size_t index, typename Func, typename... Ts>
    decltype(auto) transform_impl(Func& f, Ts&&... input) {
      return f(std::get<index>(std::forward<Ts>(input))...);
    }
    
    template <typename Func, size_t... indices, typename... Ts>
    auto transform(Func f, std::index_sequence<indices...>, Ts&&... input) {
      return std::make_tuple(transform_impl<indices>(f, std::forward<Ts>(input)...)...);
    }
    

    https://wandbox.org/permlink/c9YquHFlWlFYM0KN .

    关于c++ - 嵌套参数包扩展失败,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60123058/

    相关文章:

    c++ - glmapbufferOES 和 glunmapbuffer 在 opengl-es 2.0 中未声明

    C++模板类友元运算符重载

    C++ Boost 变体错误

    c++ - C++ 中 (n & 1 << b) 的含义

    c++ - C++ Primer 第 5 版中发现的错误 shared_ptr<int>

    c++ - 在不关闭连接的情况下循环 boost asio加密

    c++ - 算法中令人费解的行为应该根据列表的项目创建 4 个列表

    C++1z 使用 std::initializer_list<int> 处理 == 测试,在自动函数中使用和不使用 const

    c++ - 为什么 `std::async` 无法选择正确的重载?

    c++ - 可以使用对 shared_ptr 拥有的对象的引用吗?