2013-02-25 38 views
2

我试图绑定功能分为不同的类型 - 考虑以下测试程序:更好的语法来绑定函数的类型?

#include <utility> 

template <class Ret, class Arg> 
struct func { 
    typedef Ret (&ref)(Arg); 
    template <ref Fn> 
    struct bind { 
     template <class NewArg> 
     Ret operator()(NewArg&& arg) { 
      return Fn(std::forward<Arg>(arg)); 
     } 
    }; 
}; 

int foo(int i) { 
    return i; 
} 

typedef func<int, int>::bind<foo> Foo; 

int main(int argc, char** argv) { 
    Foo foo_obj; 
    return foo_obj(argc); 
} 

这工作,但我个人觉得func<int, int>::bind<foo>难看,而且它也是多余的 - 但我似乎无法做到func::bind<foo>和将Ret和Arg从模板参数中推导出来进行绑定(或者道德等价的)。我会做这样的事情:

template <class Ret, class Arg> 
constexpr auto bind_func(typename func<Ret, Arg>::ref f) -> typename func<Ret, Arg>::bind<f> { 
    return {}; 
} 

然而,由于F不保证是一个常量表达式这个不能编译,因为编译器无法知道f是一个有效的模板参数。

有没有办法做到这一点,而没有经常冗余?

+0

我会问,为什么你就不能使用'标准:: bind'? – 2013-02-25 00:48:35

+0

因为我需要的类型是constexpr默认可构造而不会丢失上下文。我不需要绑定的所有功能,我只需要能够将该函数封装在一个类型中。 – 2013-02-25 00:51:02

+4

[相关]。(http://stackoverflow.com/q/5628121/500104) – Xeo 2013-02-25 00:54:48

回答

1

如果宏接受你,这里是一个可能的解决方案:

#include <utility> 

template <class Ret, class Arg> 
struct func { 
    typedef Ret (&ref)(Arg); 
    template <ref Fn> 
    struct bind { 
     template <class NewArg> 
     Ret operator()(NewArg&& arg) { 
      return Fn(std::forward<Arg>(arg)); 
     } 
    }; 
}; 

template<typename T> 
struct traits { }; 

template<typename R, typename A> 
struct traits<R(A)> 
{ 
    typedef R return_type; 
    typedef A arg_type; 
}; 

int foo(int i) { 
    return i; 
} 

#define TYPE_WRAP(f) \ 
    func< \ 
     traits<decltype(f)>::return_type, \ 
     traits<decltype(f)>::arg_type \ 
     >::bind<f> 

int main(int argc, char** argv) { 
    TYPE_WRAP(foo) foo_obj; 
    return foo_obj(argc); 
} 
相关问题