2013-04-18 9 views
7

Ich habe versucht, mit Boost MPL in den Griff zu bekommen.Boost MPL verschachtelte Lambdas

Als einfache Übungen, habe ich versucht:

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

Diese alle gut funktionieren. Allerdings ist der folgende Versuch nicht kompilieren:

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

Ich denke, es ist etwas, mit dem Umfang der Platzhalter in negate_a_list zu tun, aber ich bin nicht sicher, wie es zu beheben. Irgendwelche Ideen? Ich vermute auch, dass einige meiner Annahmen über die Syntax und Semantik von MPL fehlerhaft sind. Ich wäre dankbar für irgendwelche Tipps zum grokking MPL.

P.S. Hier ist die Präambel für den obigen Code:

#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

Das Problem ist, dass die Platzhalter auf zwei verschiedene Anwendungsebenen verweisen: die erste muss beim Aufruf von 'apply' gebunden werden, während die zweite gebunden werden muss, wenn 'transform' aufgerufen wird. In Ihrem Code ist 'negate_a_list' eine binäre Metafunktion, während es eine unäre Metafunktion sein sollte, die eine unäre Metafunktion zurückgibt. Der Umgang mit verschachtelten lambdas kann knifflig sein, einige Antworten finden Sie in [diesem Thread auf der Boost-Mailingliste] (http://lists.boost.org/Archives/boost/2012/01/189614.php). –

+0

Erratum: 'negate_a_list' sollte nicht wirklich" eine unäre Metafunktion zurückgeben ", es ist eher eine Art Kapselung. Im Grunde ist das, was du jetzt hast, verwandt mit diesem Lambda '(x, y) => transformiere (x, negiere (y))' während du brauchst '(x) => transformiere (x, (y) => negiere (y)) '. –

Antwort

5

Dank Luc Touraille Kommentar auf meine Frage, die Boost-Mailing-Liste the answer bietet. Dieser Code funktioniert:

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

Notiere die Zugabe der lambda<...>::type Umwickeln des Lambda-Ausdruck. Dies reicht aus, um den Umfang des Platzhalters zu begrenzen.

Verwandte Themen