[lamda] smart self binding of a function object
Hi,
I usually have function-classes that take two arguments.
class f{
double operator()(double x, double y) const { x*y+y; }
};
called as:
f myf;
cout << myf(4.,3.);
for some purposes I need a function of only one variable (parametrized
in the first or second argument. So I end up doing:
using boost::function;
using namespace boost::lambda;
function
sorry for double posting, the first message had the wrong subject
[lamda] instead of [lambda].
On May 11, 3:11 am, alfC
Hi,
I usually have function-classes that take two arguments.
class f{ double operator()(double x, double y) const { x*y+y; }
};
called as:
f myf; cout << myf(4.,3.);
for some purposes I need a function of only one variable (parametrized in the first or second argument. So I end up doing:
using boost::function; using namespace boost::lambda; function
myf_at5 = bind(&f::operator(), myf, 5., _1); // myf_at5 is myf(5.,*) So, now I can pass myf_at5 to something that accepts a function of one variable.
root_finder( myf_at5, ...);
since I have access to f I would like to make f smart enough to handle its own binding. Eg.
class f{ ... // same as before function
operator()(double x_value, YYYY y_arg){ return bind( &f::operator(), //maybe needs cast to double(*) (double,double) *this, x_value, y_arg ); } function operator()(XXXX x_arg, double y_value){ return bind( &f::operator(), //maybe needs cast *this, x_arg, y_value ); } };
The question is: What should be the type of XXXX and YYYY?
in such a way that I can just call
root_finder( myf(5., _1) , ... ); or more complicated things like root_finder( myf(5., _1 * 2.), ...);
in other words, myf(5.,_1) is the same as the old bind(&f::operator(), myf, 5., _1);
Thank you, Alfredo answers using other libraries are also accepted :) _______________________________________________ Boost-users mailing list Boost-us...@lists.boost.orghttp://lists.boost.org/mailman/listinfo.cgi/boost-users
-- Sie haben diese Nachricht erhalten, da Sie der Google Groups-Gruppe Boost Users beigetreten sind. Wenn Sie Nachrichten in dieser Gruppe posten möchten, senden Sie eine E-Mail an boostusers@googlegroups.com. Wenn Sie aus dieser Gruppe austreten möchten, senden Sie eine E-Mail an boostusers+unsubscribe@googlegroups.com. Besuchen Sie die Gruppe unterhttp://groups.google.com/group/boostusers?hl=de, um weitere Optionen zu erhalten.
AMDG alfC wrote:
since I have access to f I would like to make f smart enough to handle its own binding. Eg.
class f{ ... // same as before function
operator()(double x_value, YYYY y_arg){ return bind( &f::operator(), //maybe needs cast to double(*) (double,double) *this, x_value, y_arg ); } function operator()(XXXX x_arg, double y_value){ return bind( &f::operator(), //maybe needs cast *this, x_arg, y_value ); } }; The question is: What should be the type of XXXX and YYYY?
You'll have to make operator() a template:
template<class T>
function
The question is: What should be the type of XXXX and YYYY?
You'll have to make operator() a template:
template<class T> function
operator()(const T& x_arg, double y_arg);
I was about to do that but then I though that doing so would open a can of uncontrolled overload. What if I want to restrict T to lambda expressions? what would be the best way to do it, enable_if? some special tag? (Do lambda expression have any special tag?) Thank you, Alfredo
On 11/05/2010 1:45 PM, alfC wrote:
The question is: What should be the type of XXXX and YYYY?
You'll have to make operator() a template:
template<class T> function
operator()(const T& x_arg, double y_arg); I was about to do that but then I though that doing so would open a can of uncontrolled overload. What if I want to restrict T to lambda expressions? what would be the best way to do it, enable_if? some special tag? (Do lambda expression have any special tag?)
Thank you, Alfredo
What about forcing T to be or be derived from an expression template base class?
You'll have to make operator() a template:
template<class T> function
operator()(const T& x_arg, double y_arg);
What if I want to restrict T to lambda expressions?
What about forcing T to be or be derived from an expression template base class?
How can I do that? Can you point me to the right documentation if any. In the context of Boost.Lambda there is no common base class for all expression templates (is there?), for example the placeholders do not inherit from anything. The only thing I found was the subclass 'sig' that seems to be defined for all expression types. But I am still scratching my head on how to expoit this 'sig' subclass. Now that I think one obvious way to restrict T is to be an expression template that 'returns' a double (or convertible to 'double'), this information is contained in the sig subclass. But I am confused now to do any progress. Alfredo
On 11/05/2010 7:47 PM, alfC wrote:
You'll have to make operator() a template:
template<class T> function
operator()(const T& x_arg, double y_arg); What if I want to restrict T to lambda expressions?
What about forcing T to be or be derived from an expression template base class?
How can I do that? Can you point me to the right documentation if any.
In the context of Boost.Lambda there is no common base class for all expression templates (is there?), for example the placeholders do not inherit from anything. The only thing I found was the subclass 'sig' that seems to be defined for all expression types. But I am still scratching my head on how to expoit this 'sig' subclass.
Now that I think one obvious way to restrict T is to be an expression template that 'returns' a double (or convertible to 'double'), this information is contained in the sig subclass. But I am confused now to do any progress.
Alfredo
http://en.wikibooks.org/wiki/More_C%2B%2B_Idioms/Expression-template http://www.boost.org/libs/numeric/ublas/doc/expression_concept.htm C++ Expression Templates By Angelika Langer and Klaus Kreft, March 01, 2003 http://www.drdobbs.com/184401627 I have yet to tinker with expression templates in any meaningful way (aside from copy/pasting the example from wikibooks.org and playing with it), so beyond giving you those links as guides there's not much I can do. I do know that it's exactly what you want though and that the keys to your kingdom are the Var and Constant classes (or equivalent) from the wikibooks.org article. Good luck! Geoff
On 11/05/2010 7:47 PM, alfC wrote:
You'll have to make operator() a template:
template<class T> function
operator()(const T& x_arg, double y_arg); What if I want to restrict T to lambda expressions?
What about forcing T to be or be derived from an expression template base class?
How can I do that? Can you point me to the right documentation if any.
In the context of Boost.Lambda there is no common base class for all expression templates (is there?), for example the placeholders do not inherit from anything. The only thing I found was the subclass 'sig' that seems to be defined for all expression types. But I am still scratching my head on how to expoit this 'sig' subclass.
Now that I think one obvious way to restrict T is to be an expression template that 'returns' a double (or convertible to 'double'), this information is contained in the sig subclass. But I am confused now to do any progress.
Alfredo
I'd also like to add that I'd be very interested to hear about what you've come up with as a solution. Thanks! Geoff
On May 11, 7:10 am, Steven Watanabe
since I have access to f I would like to make fsmartenough to handle its own binding. Eg. You'll have to make operator() a template: template<class T> function
operator()(const T& x_arg, double y_arg);
Thank you Steven for pointing that out.
This is simplest still useful solution I found. I realized that
returning function
On 5/27/10 3:25 PM, alfC wrote:
Maybe as OvermindDL1 said Boost.Phoenix can do better in terms of shorted syntax or by allowing CRTP in some way. Unfortunately I don't know enough Phoenix, maybe Phoenix has a "function" class that is a phoenix-lambda by itself.
Indeed, phoenix does: http://tinyurl.com/35t3yon Regards, -- Joel de Guzman http://www.boostpro.com http://spirit.sf.net
On May 27, 12:25 am, alfC
This is simplest still useful solution I found. I realized that returning function
would defeat the purpose since it is not a lambda expression an I would need bind again to insert it in a lambda expression this is the soltution (see code in previous post)
this is the generalization to function objects that take *two*
arguments,
note that there are two template parameters now.
As you see the code is still quite long, I didn't find a way to
simplify it.
(I still didn't manage to use CRTP for example.)
class A{
typedef A self_type;
...
complex operator()(quantityatomic::wavenumber const& k,
quantityatomic::frequency const& w) const{
//function that does the real work ...
}
template
On Tue, May 11, 2010 at 4:11 AM, alfC
Hi,
I usually have function-classes that take two arguments.
class f{ double operator()(double x, double y) const { x*y+y; } };
called as:
f myf; cout << myf(4.,3.);
for some purposes I need a function of only one variable (parametrized in the first or second argument. So I end up doing:
using boost::function; using namespace boost::lambda; function
myf_at5 = bind(&f::operator(), myf, 5., _1); // myf_at5 is myf(5.,*) So, now I can pass myf_at5 to something that accepts a function of one variable.
root_finder( myf_at5, ...);
since I have access to f I would like to make f smart enough to handle its own binding. Eg.
class f{ ... // same as before function
operator()(double x_value, YYYY y_arg){ return bind( &f::operator(), //maybe needs cast to double(*) (double,double) *this, x_value, y_arg ); } function operator()(XXXX x_arg, double y_value){ return bind( &f::operator(), //maybe needs cast *this, x_arg, y_value ); } }; The question is: What should be the type of XXXX and YYYY?
in such a way that I can just call
root_finder( myf(5., _1) , ... ); or more complicated things like root_finder( myf(5., _1 * 2.), ...);
in other words, myf(5.,_1) is the same as the old bind(&f::operator(), myf, 5., _1);
The way I would do this would be Boost.Phoenix, rewrite your f like (I
am not making this fully generic, although it would be easy to do,
just keeping it as doubles):
class f_impl{
template
participants (5)
-
alfC
-
Geoff Hilton
-
Joel de Guzman
-
OvermindDL1
-
Steven Watanabe