我正在尝试将函数绑定到类型中 - 请考虑以下测试程序:
#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 :(得分: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);
}