假设我有一些用C++编写和编译的函数:
int quicksum(int a, int b){ return a+b; }
int quickmult(int a, int b){ return a*b; }在运行时中,我希望能够创建这些函数的组合,比如quicksum(quickmult(5,6),7),并将其作为一个保存的过程,随时可以执行。
目前,我在Qt中使用JavaScript和C++来达到一半的目的,其中quicksum之类的函数是在C++中定义的,然后通过以下操作从JavaScript调用:
var somestring="quicksum(5,(quicksum(4,4)))"
eval(somestring)现在可以这样做了,但问题是这些函数的组合仍然在JavaScript端进行管理,这意味着JS在将其输入到另一个函数之前处理来自一个函数的返回,而不是运行整个组合本身的C++ (至少我假设是这样的)。
我不介意在JS中创建初始组合,但出于性能原因,我不希望每次需要调用函数组合时都涉及到JS。
是否有一种方法可以将这种函数组合放到C++端,并让它停留在那里以便稍后运行?我不介意将JS完全从流程中删除,这只是我能想到的唯一方法;也许在C++中有一些聪明的方法可以在运行时使用函子来动态地拼接以前编译过的函数?
更新...
我正在考虑的另一个选择是使用函子,它们本身具有引用其他函子的成员变量。这有点像在运行时创建一个带有闭包的新函数,如果JS调用带有其他函子参数的函子构造函数。那么这个函子将完全是一个C++对象,它的过程存储在(我认为)中。我得在脑子里想一想。
发布于 2014-02-28 05:08:30
评估运行时构造的函数在任何合理意义上都不会是“快速”的,除非您完成并编译它,例如到一个动态库中。
除非您只需要构造一个动态表达式树。
与下面的代码相比,您可能需要添加一些语法糖,但它展示了基本内容:
#include <iostream>
#include <functional> // std::plus, std::multiplies
#include <memory> // std::unique_ptr
#include <utility> // std::move
using namespace std;
struct Expression
{
virtual auto eval() const -> double = 0;
virtual ~Expression() {}
};
struct Number: Expression
{
double value;
auto eval() const -> double override { return value; }
Number( double v ): value( v ) {}
};
struct Binary_op: Expression
{
unique_ptr<Expression> a;
unique_ptr<Expression> b;
Binary_op( unique_ptr<Expression> _a, unique_ptr<Expression> _b )
: a( move( _a ) ), b( move( _b ) )
{}
};
template< class Impl >
struct Concrete_binary_op: Binary_op
{
auto eval() const -> double override
{ return Impl()( a->eval(), b->eval() ); }
Concrete_binary_op( unique_ptr<Expression> _a, unique_ptr<Expression> _b )
: Binary_op( move( _a ), move( _b ) )
{}
};
using Sum = Concrete_binary_op<std::plus<double>>;
using Product = Concrete_binary_op<std::multiplies<double>>;
auto number( double v )
-> unique_ptr<Number>
{ return unique_ptr<Number>( new Number( v ) ); }
auto sum( unique_ptr<Expression> a, unique_ptr<Expression> b )
-> unique_ptr<Sum>
{ return unique_ptr<Sum>( new Sum( move( a ), move( b ) ) ); }
auto product( unique_ptr<Expression> a, unique_ptr<Expression> b )
-> unique_ptr<Product>
{ return unique_ptr<Product>( new Product( move( a ), move( b ) ) ); }
auto main()
-> int
{
auto e = sum( product( number( 5 ), number( 6 ) ), number( 7 ) );
cout << e->eval() << endl;
}https://stackoverflow.com/questions/22085990
复制相似问题