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;
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). –
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)) '. –