std::function 的重载运算符?

Overload operators for std::function?

假设您想对函数执行数学运算。从数学上我们知道 f(x)*g(x) 也是一个函数,如果 fg 是。

如何用 std::function 表达这一点?我正在考虑重载数学运算符:

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

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

但我不确定 fg 的论点在这里会如何发挥作用。我可以为此使用 std::placeholders 吗?正确的处理方式是什么?

会是

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

不过我不建议这样做。其一,因为您不能向 std 添加内容,所以 ADL 无法找到此运算符,因此您必须依赖普通的非限定查找,这充其量是脆弱的。此外,多层 std::function 效率很低。

return 类型不需要类型擦除。你真的想要这样的东西:

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

这比 return 一个 std::function<double(double)> 更有效。如果调用者愿意,composed 仍然可以转换为 1。但是直接传给std::transform,直接调用composed效率更高

事实上,operator* 的工业级实现会尝试捕获 fg 的实际类型,因此 composed 将成为模板。