存储表达式模板仿函数

时间:2010-03-19 10:22:15

标签: c++ templates expression

目前我对表达式模板非常感兴趣,并希望编写一个库,用于编写和区分具有lambda样式语法的数学函数。目前,我可以写(_x * _x)(2);并获得正确的结果4.但我真的想做MathFunction f = _x * _x; f(2);之类的事情,但我对如何处理没有任何想法右侧的递归表达式模板。是否可以在不使用'auto'-Keyword而不是MathFunction或必须使operator()虚拟的情况下实现这一目标?

感谢您的帮助!

5 个答案:

答案 0 :(得分:3)

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);   
}

答案 1 :(得分:1)

嗯,Boost已经支持这个功能了,所以你可能想看看他们是如何做到的。

以下链接在我学习时非常有用:
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

第二个链接是我个人的最爱!

一切顺利。

答案 2 :(得分:1)

实际上我认为没有一种简单的方法可以存储它们。如果我想创建一个boost :: lambda表达式的命名实例,我会将结果分配给 int ,然后从编译器的错误消息中复制所需类型的名称:

#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;
}

在现实生活中,你更有可能将它们存储在类型擦除类型中,例如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);
}

答案 3 :(得分:0)

我怀疑没有虚函数就可以实现这一点。您需要进行类型擦除,因为您无法使用auto和类似的。但是后来在该范围内,因为您在类型擦除对象上调用函数,您需要运行时支持来调用派生类对象上的函数。

我怀疑没有auto你不能这样做。

答案 4 :(得分:0)

由于我是本网站的新手,我发现this直到我提交此问题为止。感谢您的回答,但这正是我真正想要的。