简体   繁体   English

std :: function的重载运算符?

[英]Overload operators for std::function?

Suppose you would like to perform mathematical operations on functions. 假设您要对函数执行数学运算。 Mathematically we know that f(x)*g(x) is also a function if f and g are. 从数学上讲,如果fgf ,则f(x)*g(x)也是一个函数。

How would one go about expressing that with std::function ? 如何用std::function表达这一点? I was thinking of overloading the mathematical operators something so: 我当时想让数学运算符重载,如下所示:

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

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

But I'm not sure how the arguments of f and g would come into play here. 但是我不确定fg的参数在这里如何发挥作用。 Could I use std::placeholders for this? 我可以为此使用std::placeholders吗? What would be the correct way to proceed? 正确的处理方式是什么?

It would be 这将是

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

I don't recommend doing it, though. 不过,我不建议您这样做。 For one, because you can't add things to std , this operator can't be found by ADL, so you have to rely on plain unqualified lookup, which is brittle at best. 首先,由于您无法将内容添加到std ,因此ADL无法找到该运算符,因此您必须依靠简单的不合格查找,这充其量是很脆弱的。 Also, multiple layers of std::function is quite inefficient. 同样,多层std::function效率很低。

There's no need for type erasure in the return type. 在返回类型中不需要类型擦除。 You'd really want something like this: 您真的想要这样的东西:

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); }

This is more efficient than return a std::function<double(double)> . 这比返回std::function<double(double)>更有效。 composed can still be convertedto one, if the caller wants to. 如果呼叫者愿意, composed仍可以转换为1。 But when you just pass it to std::transform , calling composed directly is more efficient. 但是,当你只是把它传递给std::transform ,调用composed直接更有效。

In fact, an industrial-strength implementation of operator* would try to capture the actual types of f and g as well, so composed would become a template. 实际上,一个具有operator*的行业实力的实现也会尝试捕获fg的实际类型,因此, composed将成为模板。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM