Boost.Bind - understanding placeholders
I am trying to understand the following example, that is similar (but not equal) to the one posted earlier on the SO Help understanding boost::bind placeholder arguments :
#include <boost/bind.hpp>
#include <functional>
struct X {
int value;
};
int main() {
X a = { 1 };
X b = { 2 };
boost::bind(std::less<int>(),
boost::bind(&X::value, _1),
boost::bind(&X::value, _2)开发者_如何转开发)
(a, b);
}
How is this possible, that the outer-most bind function knows that it has to pass the first argument to the second bind (that expects _1
), and the second argument to the third bind (that expects _2
)? The way I see this is that the inner binders are evaluated first, so they become two unary functional objects, that are later passed to the binder of less<int>
object. And when the newly created functional object is invoked with two objects, a
goes to the first inner-bind, and b
goes to the second. If I were right, we would use _1
twice. I must be wrong. I will repeat my question once again to make my problem clear: how the outer binder knows which placeholder was used in which inner binder?
arguments are packed in tuple (a,b) and passed to functors. then inner functor decides which tuple element it needs, e.g. try:
boost::bind(&X::value, _1)(a,b)
boost::bind(&X::value, _2)(a,b)
More generally, every value, regardless if it is constant/reference/placeholder is represented as functor which takes argument tuple and returns value.
bind(f, 10)(a) // still functor which discards arguments
Now, I am not a hundred percent sure this is how bind does it. however, this is how phoenix implement its functionality. if you are trying to understand mechanism of bind/lambda implementation, look at phoenix, it is very extensible and has excellent documentation.
精彩评论