2014-03-19 144 views
3

我在玩C++ 14 lambda(一般來說只是lambdas),我有一個函數(管道),我試圖寫。前提是它需要一個單位lambda和一個一元lambda表達式數組,然後它將在單元上運行,併產生一個新的單元,以發送到管道中的下一個單元,直到你通過最後一個lambda並返回final單元。我當前的代碼是:使用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; 
}; 

目前的問題是,鐺被踢回陣列上說:

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. 

這是根本不可能的lambda表達式?我需要鞭打std::function?我只是以這種錯誤的方式去做?

回答

7

退一步,您試圖對值序列執行(左)摺疊。因爲在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上可用 - 類型特徵別名也是如此。)