Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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?

like image 519
Marc Andreson Avatar asked Sep 20 '10 18:09

Marc Andreson


People also ask

What are boost placeholders?

Placeholders denote the arguments that are to be supplied to the resulting function object, and Boost. Bind supports up to nine such arguments. The placeholders are called _1, _2, _3, _4, and so on up to _9, and you use them in the places where you would ordinarily add the argument.

What is _1 in boost :: bind?

_1 is a placeholder. Boost. Bind defines placeholders from _1 to _9 . These placeholders tell boost::bind() to return a function object that expects as many parameters as the placeholder with the greatest number.

What is the purpose of boost bind?

Purpose. boost::bind is a generalization of the standard functions std::bind1st and std::bind2nd. It supports arbitrary function objects, functions, function pointers, and member function pointers, and is able to bind any argument to a specific value or route input arguments into arbitrary positions.

What is a placeholder in C++?

Placeholders are namespaces which detect the position of a value in a function. Placeholders are represented by _1, _2, _3 etc.


1 Answers

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.

like image 123
Anycorn Avatar answered Oct 09 '22 21:10

Anycorn