目前我对表达式模板非常感兴趣,并希望编写一个库,用于编写和区分具有lambda样式语法的数学函数。目前,我可以写(_x * _x)(2);
并获得正确的结果4.但我真的想做MathFunction f = _x * _x; f(2);
之类的事情,但我对如何处理没有任何想法右侧的递归表达式模板。是否可以在不使用'auto'-Keyword而不是MathFunction或必须使operator()虚拟的情况下实现这一目标?
感谢您的帮助!
答案 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直到我提交此问题为止。感谢您的回答,但这正是我真正想要的。