1

假设我想要一个函数double adapter(double),有没有一种通用的方法可以用 a 组合它boost::function<double(...)> functor来产生另一个boost::function<double(...)> functor2where functor2(...) == adapter(functor(...))?特别是,如果有一种方法可以在不使用 C++11 的情况下做到这一点,那就太酷了。

编辑澄清一下,我很想知道是否有办法编写可以处理 any 的东西boost::function<double(...)>,即具有不同长度签名的东西,而不必为 1、2、3 等参数多次复制和粘贴。

4

1 回答 1

2

如果没有 c++11,就会有大量的复杂性,包括可变参数和转发。

使用 C++11,它可以完成,主要是通过专门化std::is_bind_expression. 在绑定中使用此函数对象时,它会调用与在调用绑定函数对象期间提供的所有参数一起存储的函数对象。请注意,这适用于任何函数对象,而不仅仅是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;
}
于 2012-09-13T20:05:37.900 回答