【发布时间】:2020-12-31 08:14:18
【问题描述】:
我正在尝试创建一个函数“compose”,返回作为参数给出的可调用对象的组合。
在数学中,应该是这样的:
F = h(g(f(x)))
这里是 C++ 的实现:
template <typename F>
auto compose(F&& f)
{
return[f = std::forward<F>(f)](auto&&... args){
return f(std::forward<decltype(args)>(args)...);
};
}
template <typename F, typename G, typename... Functions>
auto compose(F&& f, G&& g, Functions&&... functions)
{
return compose(
[f = std::forward<F>(f), g = std::forward<G>(g)](auto&&... args)
{
return f(g(std::forward<decltype(args)>(args)...));
},
std::forward<Functions>(functions)...);
}
如果我提供 lambda 函数作为参数,这就像一个魅力:
auto f = compose(
[](auto value) { return std::sin(value); },
[](auto value) { return std::asin(value); }
);
但是,如果我直接使用标准中的重载函数(没有将它们封装在 lambda 中),编译器将无法推断选择哪个重载来实例化模板:
auto g = compose(
std::sin,
std::asin
);
这里使用 Microsoft C++ 编译器的错误:
error C2672: 'compose': no matching overloaded function found
error C2783: 'auto compose(F &&,G &&,Functions &&...)': could not deduce template argument for 'F'
message : see declaration of 'compose'
error C2783: 'auto compose(F &&,G &&,Functions &&...)': could not deduce template argument for 'G'
message : see declaration of 'compose'
error C2780: 'auto compose(F &&)': expects 1 arguments - 2 provided
message : see declaration of 'compose'
有没有办法在创建组合函数时说明我们想要使用的函数类型(std::sin 和 std::asin)?
【问题讨论】:
-
我不认为有什么好办法。有些人使用宏方便地将函数包装在宏中。
-
为什么不立即传入你的数据类型,以便你可以使用呢?例如。
compose<double>(...)。那么应该像魅力一样工作
标签: c++ functional-programming