I've got a situation where I have a series of member functions which produce simple information on a target object:
double MyDoc::GetX(thing)
double MyDoc::GetY(thing)
etc.
I've made some "pretty formatting" member functions in the same class:
string MyDoc::PrintOne(thing, std::function<double (THING*)>)
You'll notice that the pretty-printer function takes a data-function - i.e. it is composable so that I can create various types of information about a target and produce a "pretty print" string for it.
In direct usage, this technique works beautifully.
However, what I really want for my current application is to compose multiple layers of such entities - i.e. effectively create a functor (function object) for the above composition as a whole, such that I can specify pretty-printer function, and it's data-acquisition function, and call that later. Pattern is z(x) -> f(x, g(x)):
auto Z = [&] (THING* thing) {
return boost::bind(
&MyDoc::PrintOne,
this,
_1,
boost::bind(MyDoc::GetX, this, _1));
}
And here is where I run into problems. I am going in circles trying to get the syntax right, or maybe I'm getting confused with the boost::bind syntax versus the C++ lambda syntax, or maybe I'm just fundamentally misunderstanding something?
Basically, I want to compose a function Z which takes a THING* and another function X which also takes a THING* and, using logic of its own, produces a string output for a given THING*.
I have variations - some take two data-accessor type functions, or maybe a bool + data accessor. Doesn't really matter - the bottom line should be the same:
How do I compose Z where Z -> F(x, G(x))?
Thanks for any and all help!
boost::bind
(and std::bind
) eagerly evaluates nested bind expressions, so what you have would match a signature string MyDoc::PrintOne(THING*, double)
. To prevent eager evaluation and return the nested bind expression directly (suitable for constructing a std::function<>
), use boost::protect
:
boost::bind(
&MyDoc::PrintOne,
this,
_1,
boost::protect(boost::bind(&MyDoc::GetX, this, _1))
)
This is outlined in the section of the documentation titled "using nested binds for function composition".