【问题标题】:Using an array of lambda arguments使用 lambda 参数数组
【发布时间】:2014-03-19 08:52:27
【问题描述】:

我正在使用 C++14 lambdas(实际上只是 lambdas),并且我有一个我正在尝试编写的函数(管道)。前提是它将采用一个单元 lambda 和一个一元 lambda 数组,然后它将在该单元上运行并生成一个新单元以发送到管道中的下一个单元,直到您通过最后一个 lambda 并返回最终单元。我当前的代码是:

auto pipeline = [](auto u, auto callbacks[]){
  for(int i = 0; i<sizeof(callbacks)/sizeof(callbacks[0]);i++){
     u = bind(u,callbacks[i]);
  }
  return u;
};

当前的问题是,clang 正在对数组进行反击:

testFuture.cpp:183:111: error: no matching function for call to object of type 'func::<lambda at ./func.hpp:30:19>'
  cout<<"pipeline(unit(10),{addf(4),curry(mul,2)}):"<<bind(unit(bind(unit(10))(addf(4))))(curry(mul,2))<<"|"<<pipeline(unit(10),{{addf(4),curry(mul,2)}})()<<endl;
                                                                                                              ^~~~~~~~
./func.hpp:30:19: note: candidate template ignored: couldn't infer template argument '$auto-0-1'
  auto pipeline = [](auto u, auto callbacks[]){
                  ^
1 error generated.

这对 lambdas 来说是不可能的吗?我需要抽出std::function吗?我是不是走错了路?

【问题讨论】:

    标签: c++ lambda c++14


    【解决方案1】:

    退后一步,您正在尝试对一系列值执行(左)折叠。因为在 C++ 中,每个闭包都有一个唯一的类型,所以您希望在元组而不是数组上进行折叠。作为一个额外的好处,我们将更通用并接受具有任何返回类型的函子,如果我们不能这样做,例如我们使用std::function 来模拟箭头类型。

    #include <utility>      // std::forward, std::integer_sequence
    #include <type_traits>  // std::remove_reference_t
    #include <tuple>        // tuple protocol, e.g. std::get, std::tuple_size
    
    namespace detail {
    
    template<typename Functor, typename Zero, typename Tuple, typename Int>
    Zero foldl(Functor&&, Zero&& zero, Tuple&&, std::integer_sequence<Int>)
    { return std::forward<Zero>(zero); }
    
    template<typename Functor, typename Zero, typename Tuple, typename Int, Int Index, Int... Indices>
    decltype(auto) foldl(Functor&& functor, Zero&& zero, Tuple&& tuple, std::integer_sequence<Int, Index, Indices...>)
    { return detail::foldl(
            functor
            , functor(std::forward<Zero>(zero), std::get<Index>(std::forward<Tuple>(tuple)))
            , std::forward<Tuple>(tuple)
            , std::integer_sequence<Int, Indices...> {}); }
    
    } // detail
    
    template<typename Functor, typename Zero, typename Tuple>
    decltype(auto) foldl(Functor&& functor, Zero&& zero, Tuple&& tuple)
    {
        return detail::foldl(
                std::forward<Functor>(functor)
                , std::forward<Zero>(zero)
                , std::forward<Tuple>(tuple)
                , std::make_index_sequence<std::tuple_size<std::remove_reference_t<Tuple>>::value>()
                );
    }
    

    您还没有告诉我们bind 应该实现什么,但here’s an example 涉及函数的反向组合。 (包括integer_sequence 和朋友的有限实现,因为它们似乎在 Coliru 上不可用——也缺少类型特征别名。)

    【讨论】:

      猜你喜欢
      • 2019-12-02
      • 2021-11-17
      • 1970-01-01
      • 1970-01-01
      • 2017-05-04
      • 2017-10-06
      • 1970-01-01
      • 2016-06-10
      • 1970-01-01
      相关资源
      最近更新 更多