
Thanks Maxim, I appreciate the help. I tried the code out, it works well, but I must confess that I don't understand how it works. It seems you start it at begin+1. I don't know why but it's probably related to the next question. What is happening on this line? mpl::plus<mpl::deref<mpl::_2>, mpl::_1> As near as I can tell you deref the iterator in <_2> and add that with _1. How does this _1 and _2 stuff work anyway? Thanks again! -Dan

"Dan" <dan@eloff.info> wrote
How does this _1 and _2 stuff work anyway?
From my experience, in order to understand this stuff, you first have to temporarily forget about _1 and _2 (unless you are already fluent with Boost.Lambda).
An MPL algorithm (fold, iter_fold, etc.) actually accepts 3 parameters: 1) sequence; 2) initial type (state); 3) metafunction class. The third parameter defines how to create a new state from the old state and the current element (or iterator) of the sequence, for your example something like this: struct adder { template<class State, class Current> struct apply { typedef typename mpl::plus<State, Current>::type type; }; }; (this may not compile -- I am not sure about the order of template parameters) The adder is analogous to a functor in STL, and apply is analogous to the function call operator. Having defined this "functor", you can get your result something like this: typedef mpl::fold<MySequence, mpl::int_<0>, adder>::type MyResult; As far as _1, _2, etc., is concerned -- this is MPL Lambda facility, it allows to define metafunction classes right in-place, in the same way Boost.Lambda does for runtime functors. I believe (I may be wrong of course) that MPL Lambda is more complicated than the rest of MPL, but, in short, _1 stands for the first parameter of apply, and _2 -- for the second parameter. When you write: mpl::plus<mpl::_2, mpl::_1> this effectively (by the means of MPL Lambda) defines a metafunction class ("functor") that acts in the same way as the "adder" does. HTH, Arkadiy

Dan <dan@eloff.info> wrote:
It seems you start it at begin+1. I don't know why but it's probably related to the next question.
mpl::fold algorithms resemble std::accumulate (the version that takes a binary functor) the only difference being that high level mpl algorithms (mpl::fold is among of them) take ranges instead of [first, last) iterators. I wonder, why mpl creators adhering stl concepts chose 'fold' name instead of 'accumulate' name which is well-known for c++ programmers? Just like std::accumulate mpl::fold takes an initial value. If I were to provide that initial value in that code snippet by myself I would have to deduce the type of the sequence elements which may have different types. So, I simply took the first element of the sequence as the initial value and then iterated on [first + 1, last).
What is happening on this line?
mpl::plus<mpl::deref<mpl::_2>, mpl::_1>
Here is a mpl::lambda expression which results in metufunction that takes two arguments, dereferences the second and then adds them. It might have been written as mpl::plus<mpl::_1, mpl::deref<mpl::_2> > as well, but in the latter case you will have to insert a space between the adjacent '> >' at the end, so I rearranged it :). As it already was mentioned you might want use mpl::fold instead of mpl::iter_fold. The former will save you from typing that deref in the lambda expression (that is, mpl::plus<mpl::_, mpl::_> using unnamed placeholders as we don't care about the order of arguments any more).
As near as I can tell you deref the iterator in <_2> and add that with _1.
Exactly.
How does this _1 and _2 stuff work anyway?
They are placeholders, the same concept like in boost::bind and boost::lambda. You might like reading mpl docs, it explains the stuff. -- Maxim Yegorushkin
participants (3)
-
Arkadiy Vertleyb
-
Dan
-
Maxim Yegorushkin