Ho cercato di fare i conti con Boost MPL.Boost lambda MPL nidificato
Come semplici esercizi, ho provato:
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));
Questi tutti funzionano bene. Tuttavia, il tentativo successivo non viene compilato:
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));
Penso che sia qualcosa a che fare con la portata dei segnaposto in negate_a_list
, ma non sono sicuro come risolvere il problema. Qualche idea? Sospetto anche che alcune delle mie supposizioni sulla sintassi e sulla semantica di MPL siano difettose. Sarei grato per qualsiasi consiglio su Grokking MPL.
P.S. Ecco il preambolo per il codice precedente:
#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;
Il problema è che i segnaposto si riferiscono a due diversi livelli di applicazione: il primo deve essere associato quando si chiama 'apply', mentre il secondo deve essere associato quando si chiama' transform'. Nel tuo codice, 'negate_a_list' è una metafunzione binaria, mentre dovrebbe essere una metafunzione unaria che restituisce una metafunzione unaria. Affrontare i lambda nidificati può essere complicato, potresti trovare delle risposte in [questo thread sulla mailing list di Boost] (http://lists.boost.org/Archives/boost/2012/01/189614.php). –
Erratum: 'negate_a_list' non dovrebbe" restituire una metafunzione unaria ", è piuttosto una specie di incapsulamento. Fondamentalmente, ciò che hai ora è simile a questo lambda '(x, y) => transform (x, negate (y))' mentre hai bisogno di '(x) => transform (x, (y) => negate (y)) '. –