в данный момент я действительно интересуюсь шаблонами выражения, и хотят кодировать библиотеку для записи и дифференциации математических функций с синтаксисом стиля лямбды. В данный момент я могу записать (_x * _x)(2);
и получите корректный результат 4. Но я действительно хотел бы сделать что-то как MathFunction f = _x * _x; f(2);
, но у меня нет идей о том, как справиться с рекурсивными шаблонами выражения на правой стороне. Действительно ли возможно достигнуть этого, не используя 'автоматическое '-ключевое-слово вместо MathFunction или имея необходимость сделать оператор () виртуальным?
Спасибо за помощь!
Поскольку я новичок на этом сайте, я нашел это только после того, как отправил этот вопрос. Спасибо за ответы, но это то, что я действительно искал.
.
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);
}
Я сомневаюсь, что это возможно без виртуальной функции. Вам нужно стереть тип, так как вы не можете использовать 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;
}
In в реальной жизни вы, скорее всего, сохраните их в типе, который стирает тип, например 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);
}
Ну, 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
Вторая ссылка - моя личная любимая!
Всего наилучшего.