Хранение выражения обрабатывает функторы по шаблону

в данный момент я действительно интересуюсь шаблонами выражения, и хотят кодировать библиотеку для записи и дифференциации математических функций с синтаксисом стиля лямбды. В данный момент я могу записать (_x * _x)(2); и получите корректный результат 4. Но я действительно хотел бы сделать что-то как MathFunction f = _x * _x; f(2);, но у меня нет идей о том, как справиться с рекурсивными шаблонами выражения на правой стороне. Действительно ли возможно достигнуть этого, не используя 'автоматическое '-ключевое-слово вместо MathFunction или имея необходимость сделать оператор () виртуальным?

Спасибо за помощь!

5
задан fhenneke 19 March 2010 в 10:22
поделиться

5 ответов

Поскольку я новичок на этом сайте, я нашел это только после того, как отправил этот вопрос. Спасибо за ответы, но это то, что я действительно искал.

0
ответ дан 14 December 2019 в 19:09
поделиться

.

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);   
}
3
ответ дан 14 December 2019 в 19:09
поделиться

Я сомневаюсь, что это возможно без виртуальной функции. Вам нужно стереть тип, так как вы не можете использовать auto и тому подобное. Но позже в этой области, поскольку вы вызываете функцию для объекта с удаленным типом, вам потребуется поддержка времени выполнения, чтобы вызвать функцию для объекта производного класса.

Я подозреваю, что без auto вы не сможете этого сделать.

0
ответ дан 14 December 2019 в 19:09
поделиться

На самом деле я не думаю, что существует простой способ их хранения. Если бы я хотел создать именованный экземпляр выражения 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);
}
1
ответ дан 14 December 2019 в 19:09
поделиться

Ну, 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

Вторая ссылка - моя личная любимая!

Всего наилучшего.

1
ответ дан 14 December 2019 в 19:09
поделиться
Другие вопросы по тегам:

Похожие вопросы: