2015-08-19 4 views
0

Предположим, вы хотите выполнить математические операции над функциями. Математически мы знаем, что f(x)*g(x) также является функцией, если f и g.Операторы перегрузки для std :: function?

Как можно было бы выразить это с помощью std::function? Я думал о перегрузке математических операторов что-то так:

typedef std::function<double(double)> func; 

func operator * (const func &f, func &g) 
{ 
     auto temp = [&]() { return f(??) * g (??); }; 
     return temp; 
} 

Но я не знаю, как аргументы f и g вступят в игру здесь. Могу ли я использовать std::placeholders для этого? Каким будет правильный способ?

ответ

2

Было бы

func operator* (const func &f, const func &g) 
{ 
     return [=](double x) { return f(x) * g(x); } 
} 

Я не рекомендую делать это, хотя. Во-первых, потому что вы не можете добавить вещи в std, этот оператор не может быть найден ADL, поэтому вам нужно полагаться на простой неквалифицированный поиск, который в лучшем случае является хрупким. Кроме того, несколько уровней std::function довольно неэффективны.

+0

Спасибо! Должен был подумать об этом :) – nbubis

1

Нет необходимости в стирании типа в возвращаемом типе. Вы бы действительно хотите что-то вроде этого:

class composed { 
    std::function<double(double)> f; 
    std::function<double(double)> g; 
public: 
    composed(std::function<double(double)> f, std::function<double(double)> g) : f(f), g(g) { } 
    double operator()(double x) { return f(x) * g(x); } 
}; 
inline composed operator*(std::function<double(double)> f, std::function<double(double)> g) { return composed(f,g); } 

Это более эффективно, чем возвращать std::function<double(double)>. composed все еще может быть преобразован в один, если вызывающий хочет. Но когда вы просто передаете его std::transform, вызов composed напрямую более эффективен.

На самом деле, реализация индустриально-сила operator* попытается захватить фактические типы f и g, так что composed станет шаблоном.

Смежные вопросы