C++ 存储表达式模板函子

C++ 存储表达式模板函子,c++,templates,expression,C++,Templates,Expression,目前,我对表达式模板非常感兴趣,希望编写一个库,用lambda风格的语法编写和区分数学函数。目前,我能写(\ux*\ux)(2)并获得正确的结果4。但是我真的想做一些类似于MathFunction f=\ux*\ux;f(2),但我不知道如何处理右侧的递归表达式模板。是否可以在不使用“auto”关键字而不使用MathFunction或不必将运算符()设置为虚拟的情况下实现这一点 谢谢你的帮助 嗯,Boost已经支持这个功能了,所以你可能想看看他们是如何做到的 以下链接在我学习时非常有用: 第

目前,我对表达式模板非常感兴趣,希望编写一个库,用lambda风格的语法编写和区分数学函数。目前,我能写
(\ux*\ux)(2)并获得正确的结果4。但是我真的想做一些类似于
MathFunction f=\ux*\ux;f(2),但我不知道如何处理右侧的递归表达式模板。是否可以在不使用“auto”关键字而不使用MathFunction或不必将运算符()设置为虚拟的情况下实现这一点


谢谢你的帮助

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

以下链接在我学习时非常有用:

第二个链接是我个人最喜欢的

祝你一切顺利。

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);   
}
模板
结构MathFuncBase
{
虚拟R运算符()(常量T&v)=0;
虚拟~MathFuncBase(){}
};
缓和
结构MathFunc:MathFuncBase
{
MathFunc(Func Func):Func(Func){
虚拟R运算符()(常量T&v){
返回函数(v);
}
私人:
Func Func;
};
缓和
boost::shared_ptr GetMathFunc(Func Func){
返回boost::shared_ptr(newmathfunc(func));
}
int main(){
boost::shared_ptr f=GetMathFunc(_x*_x);
申报表(*f)(2);
}

如果没有虚拟功能,我怀疑这是可能的。由于不能使用
auto
和类似功能,因此需要进行类型擦除。但稍后在该范围内,由于您正在对类型擦除对象调用函数,因此需要运行时支持来调用派生类对象上的函数


我怀疑没有
auto
你就做不到

因为我是这个网站的新手,所以直到我提交了这个问题,我才发现。谢谢你的回答,但这正是我真正想要的。

事实上,我认为没有一种简单的方法来存储它们。如果我想创建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.Lambda文档以找到解决问题的方法,但是我没有找到一行Lambda函数实际上是“存储”的,它们总是内联使用。目前,我使用“C++模板-明确指南”方法来创建表达式模板。你已经看过了吗?
MathFuncBase
destructor应该是虚拟的。否则当
共享\u ptr
超出范围时,它将具有未定义的行为。虚拟析构函数很好。但是在
共享的情况下
就不需要了。看看这个。我想你是想提供一个在某处丢失的参考资料。。。无论如何,使用
shared\u ptr
您可以将自己的deleter作为参数提供给构造函数,但在上面的代码块中,您没有提供它。如果您不向
共享\u ptr
构造函数提供第二个参数,则销毁时它将调用存储指针类型的
delete
MathFuncBase
)。在这种特殊情况下,UB很可能不会产生任何(坏的)影响(无论是基对象还是派生对象都不包含任何成员,也不执行任何初始化或销毁),但它仍然是UB。@David Rodríguez:
销毁时,它将对存储指针的类型调用delete
不正确。销毁时,它将对作为第一个参数传递的模板指针类型调用delete(
MathFunc
,而不是基类)。只需检查一下。在花了几分钟的时间来实现
boost::shared\u ptr
之后,您是对的。我的想法错了。如果允许的话,我会再次投票给你答案:)谢谢你的指点。
#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);
}