2013-04-18 13 views
7

Próbowałem dostać się do uchwytu z Boost MPL.Zwiększenie MPL zagnieżdżone lambdas

tak proste ćwiczenia, próbowałem:

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)); 

to wszystko działa dobrze. Jednak następujące próba nie kompiluje:

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)); 

myślę, że to ma coś wspólnego z zakresem zastępcze w negate_a_list, jednak nie jestem pewien, jak to naprawić. Jakieś pomysły? Podejrzewam również, że niektóre z moich założeń dotyczących składni i semantyki MPL są błędne. Byłbym wdzięczny za wszelkie wskazówki dotyczące grokowania MPL.

P.S. Oto preambuła do powyższego kodu:

#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

Problem polega na tym, że symbole zastępcze odnoszą się do dwóch różnych poziomów zastosowania: pierwszy musi być związany z wywołaniem 'apply', podczas gdy drugi musi być związany podczas wywoływania' transform'. W twoim kodzie 'negate_a_list' to binarna metafunkcja, podczas gdy powinna to być jedyna metafunkcja zwracająca unarne metafunkcje. Radzenie sobie z zagnieżdżonymi lambdami może być trudne, możesz znaleźć odpowiedzi w [tym wątku na liście mailingowej Boost] (http://lists.boost.org/Archives/boost/2012/01/189614.php). –

+0

Erratum: 'negate_a_list' nie powinno naprawdę" zwracać unarnej metafunkcji ", jest to raczej rodzaj enkapsulacji. Zasadniczo to, co masz teraz, jest podobne do tej transformacji lambda '(x, y) => (x, negate (y))' podczas gdy potrzebujesz '(x) => transform (x, (y) => negate (y)) '. –

Odpowiedz

5

Dzięki komentarzu Luc Touraille jest na moje pytanie, lista dyskusyjna doładowania zapewnia the answer. Ten kod działa:

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)); 

Uwaga dodanie lambda<...>::type owijania wokół wyrażenia lambda. Jest to wystarczające, aby ograniczyć zakres elementu zastępczego.