2013-04-18 51 views
7

我一直試圖去與Boost MPL交手。Boost MPL嵌套lambdas

作爲簡單的練習,我想:

typedef vector_c<int, 1, 2, 3, 4, 5>::type example_list; 

typedef transform<example_list, times<_, int_<2> > >::type doubled_example_list; 

typedef transform<example_list, negate<_> >::type negated_example_list; 

BOOST_STATIC_ASSERT((at_c<negated_example_list, 2>::type::value==-3)); 
BOOST_STATIC_ASSERT((at_c<doubled_example_list, 4>::type::value==10)); 

這些都做工精細。但是,下面的嘗試無法編譯:

typedef transform<_, negate<_> > negate_a_list; 

typedef apply<negate_a_list, example_list>::type negated_example_list_2; 

BOOST_STATIC_ASSERT((at_c<negated_example_list_2, 2>::type::value==-3)); 

我認爲這是值得做的佔位符在negate_a_list範圍,但我不知道如何解決它。有任何想法嗎?我也懷疑我對MPL語法和語義的一些假設是有缺陷的。我會很感激任何提示MPL的提示。

P.S.下面是上面的代碼的序言:

#include <boost/mpl/vector_c.hpp> 
#include <boost/mpl/transform.hpp> 
#include <boost/static_assert.hpp> 
#include <boost/mpl/placeholders.hpp> 
#include <boost/mpl/times.hpp> 
#include <boost/mpl/size_t.hpp> 
#include <boost/mpl/apply.hpp> 
#include <boost/mpl/lambda.hpp> 
#include <boost/mpl/negate.hpp> 
#include <boost/mpl/at.hpp> 

using namespace boost::mpl; 
using namespace boost::mpl::placeholders; 
+2

問題是佔位符引用了兩個不同級別的應用程序:第一個在調用'apply'時需要綁定,而第二個在調用'transform'時必須綁定。在你的代碼中,'negate_a_list'是一個二元函數,它應該是一元函數,返回一元函數。處理嵌套lambdas可能會很棘手,您可以在[Boost郵件列表中的此線程](http://lists.boost.org/Archives/boost/2012/01/189614.php)中找到一些答案。 –

+0

錯誤:'negate_a_list'不應該真的「返回一元函數」,它只是一種封裝。基本上,當你需要'(x)=> transform(x,(y)=> negate(y)時,你現在擁有類似於這個lambda'(x,y)=> transform ))'。 –

回答

5

2009年,由於我的問題呂克Touraille的評論,Boost郵件列表提供the answer。此代碼的工作:

typedef transform<_, lambda<negate<_> >::type > negate_a_list; 

typedef apply<negate_a_list, example_list>::type negated_example_list_2; 

BOOST_STATIC_ASSERT((at_c<negated_example_list_2, 2>::type::value==-3)); 

注意除了周圍的lambda表達式的lambda<...>::type包裝的。這足以限制佔位符的範圍。