假设我想要一个函数 double adapter(double)
, 有没有一种通用的方法来将它与 boost::function<double(...)> functor
组合起来?生产另一个boost::function<double(...)> functor2
其中 functor2(...) == adapter(functor(...))
?特别是,如果有一种方法可以在不使用 C++11 的情况下执行此操作,那就太棒了。
编辑 为了澄清,我很想知道是否有一种方法可以编写可以处理任何 boost::function<double(...)>
的东西。 ,即具有不同长度签名的签名,而不必为 1、2、3 等参数多次复制和粘贴。
最佳答案
如果没有 c++11,就会有大量的复杂性,包括可变参数和转发。
在 C++11 中,这可以做到,主要是通过特化 std::is_bind_expression
。当在绑定(bind)中使用此函数对象时,它会调用与调用绑定(bind)函数对象期间提供的所有参数一起存储的函数对象。请注意,这适用于任何函数对象,而不仅仅是 std::function
。
这适用于 GCC 4.7。
#include <functional>
#include <utility>
#include <type_traits>
namespace detail
{
template<typename Func>
struct compose_functor
{
Func f;
explicit compose_functor(const Func& f) : f(f) {};
template<typename... Args>
auto operator()(Args&&... args) const -> decltype(f(std::forward<Args>(args)...))
{
return f(std::forward<Args>(args)...);
}
};
}
template<typename Func>
detail::compose_functor
<Func> compose(Func f)
{
return detail::compose_functor<Func>(f);
}
namespace std
{
template<typename T>
struct is_bind_expression< detail::compose_functor<T> > : true_type {};
}
#include <numeric>
int adapter(double d)
{
return (int)d;
}
int main()
{
std::function<int(double)> f1 = std::bind(adapter, compose(std::negate<double>()));
std::function<int(double, double)> f2 = std::bind(adapter, compose(std::plus<double>()));
// 1.5 -> -1.5 -> -1
std::cout << f1(1.5) << std::endl;
// 2.3+4.5 = 6.8 -> 6
std::cout << f2(2.3, 4.5) << std::endl;
}
关于c++ - boost 函数组成,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12412692/