2010-04-07 58 views
3

C++ 0x不贊成使用舊綁定器,例如bind1stbind2nd,而贊成使用通用std::bind。 C++ 0x lambdas與std::bind很好地結合,但它們不會與經典的bind1st和bind2nd綁定,因爲默認情況下,lambda沒有嵌套的typedefs,如argument_type,first_argument_type,second_argument_type和。 所以我認爲std::function可以作爲一個標準的方式來綁定lambda到舊的活頁夾,因爲它暴露了必要的typedefs。使用不推薦使用的綁定器和C++ 0x lambdas

但是,在這種情況下使用std::function很難使用,因爲它強制您在實例化它時闡明函數類型。

auto bound = 
    std::bind1st(std::function<int (int, int)>([](int i, int j){ return i < j; }), 10); // hard to use 
auto bound = 
    std::bind1st(std::make_function([](int i, int j){ return i < j; }), 10); // nice to have but does not compile. 

我找不到方便的對象生成器std::function。像std::make_fuction就好了。這樣的事情存在嗎?如果不是,還有沒有其他更好的方式將拉姆達斯與經典活頁夾綁定?

+0

請注意,使用傳統綁定器和lambda表達式可能會對傳統庫有用,這些庫希望它們的函數對象類型顯示上述typedef。所以我不認爲香草lambda可以用於這樣的圖書館。 – Sumant 2010-04-07 16:35:43

回答

2

從來沒有試圖做這樣的事情,我沒有時間提供完整的答案,但我想可以用Boost.FunctionTypes做些事情。

這裏有一個粗略的,不完整的和未經考驗的草稿給你一個想法:

template <typename T> 
struct AdaptedAsUnary : T 
{ 
    namespace bft = boost::function_types; 
    namespace bmpl = boost::mpl; 

    typedef typename bft::result_type<T>::type result_type; 
    typedef typename bmpl::front<typename bft::parameter_types<T>::type>::type argument_type; 

    AdaptedAsUnary(T t) : T(t) {} 
}; 

template <typename T> 
AdaptedAsUnary<T> 
AdaptAsUnary(T t) 
{ 
    return AdaptedAsUnary<T>(t); 
} 
+1

這是一個很好的解決方案。從lambda類型繼承對我來說是新的,並在g ++ 4.5中很好地工作。儘管如今,boost :: function_types(1.42)不支持lambdas作爲內置的可調用類型,但我可以找到出路。將來,當他們支持它時(我希望),這個解決方案可以按原樣使用。現在,我用http://stackoverflow.com/questions/2562320/specializing-a-template-on-a-lambda-in-c0x作爲boost :: function_types內省功能的替代品。對lambda表達式使用這些function_traits,從T和std :: unary_function的多重繼承工作。 – Sumant 2010-04-07 22:46:06

1

我不知道爲什麼你仍然需要bind1st等我能想到的唯一的事情是支持舊代碼。實際上,bind1st(f, a)可以替換爲[a](v){ return f(a, v); }等,這是一個通用的解決方案。