2013-04-18 10 views
7

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; 
+2

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

+0

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

risposta

5

Grazie al commento di Luc Touraille sulla mia domanda, il Boost mailing list fornisce the answer. Questo codice funziona:

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

nota l'aggiunta del lambda<...>::type involucro intorno alla espressione lambda. Questo è sufficiente per limitare l'ambito del segnaposto.

Problemi correlati