std::function 的重载运算符?
Overload operators for std::function?
假设您想对函数执行数学运算。从数学上我们知道 f(x)*g(x)
也是一个函数,如果 f
和 g
是。
如何用 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
吗?正确的处理方式是什么?
会是
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*
的工业级实现会尝试捕获 f
和 g
的实际类型,因此 composed
将成为模板。
假设您想对函数执行数学运算。从数学上我们知道 f(x)*g(x)
也是一个函数,如果 f
和 g
是。
如何用 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
吗?正确的处理方式是什么?
会是
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*
的工业级实现会尝试捕获 f
和 g
的实际类型,因此 composed
将成为模板。