at the moment I'm really interested in expression templates and want to code a library for writing and differentiating mathematical functions with a lambda-style syntax. At the moment, I'm able to write (_x * _x)(2);
and get the correct result 4. But I would really like to do something like MathFunction f = _x * _x; f(2);
, but I don't have any ideas on how to cope with the recursive expression templates on the right side. Is it possible to achieve this without using the 'auto'-Keyword instead of MathFunction or having to make the operator() virtual?
Thanks for your help!
.
template<class T, class R>
struct MathFuncBase
{
virtual R operator()(const T & v) = 0;
virtual ~MathFuncBase() {}
};
tempate<class T, class R, class Func>
struct MathFunc : MathFuncBase<T, R>
{
MathFunc(Func func) : func(func) {}
virtual R operator()(const T & v) {
return func(v);
}
private:
Func func;
};
tempate<class T, class R, class Func>
boost::shared_ptr<MathFuncBase<T, R> > GetMathFunc(Func func) {
return boost::shared_ptr<MathFuncBase<T, R> >(new MathFunc<T, R, Func> (func));
}
int main () {
boost::shared_ptr<MathFuncBase<int, int> > f = GetMathFunc<int,int> (_x * _x);
return (*f)(2);
}
Well, Boost already supports this functionality already, so you may want to take a look at how they have done it.
The following links were really helpful when I was learning:
http://en.wikibooks.org/wiki/More_C%2B%2B_Idioms/Expression-template
http://www.angelikalanger.com/Articles/Cuj/ExpressionTemplates/ExpressionTemplates.htm
http://www.flipcode.com/archives/Faster_Vector_Math_Using_Templates.shtml
The second link is my personal favourite!
All the best.
Actually I don't think there is a simple way to store them. If I wanted to create a named instance of boost::lambda expression, I would assign the result to, say, int and then copy the name of the needed type from the compiler's error message:
#include <boost/lambda/lambda.hpp>
int main()
{
using namespace boost::lambda;
//int x = _1 + _2;
boost::lambda::lambda_functor<boost::lambda::lambda_functor_base<
boost::lambda::arithmetic_action<boost::lambda::plus_action>,
boost::tuples::tuple<boost::lambda::lambda_functor<boost::lambda::placeholder<1> >,
boost::lambda::lambda_functor<boost::lambda::placeholder<2> >,
boost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type,
boost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type,
boost::tuples::null_type, boost::tuples::null_type> > > x = _1 + _2;
}
In real life you'd be more likely to store them in a type, that does type erasure, like boost::function
.
#include <boost/lambda/lambda.hpp>
#include <boost/function.hpp>
int main()
{
using namespace boost::lambda;
boost::function<int(int, int)> x = _1 + _2;
return x(-1, 1);
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With