我这段代码似乎有效:
template <typename C>
class class_ {
protected:
std::map<std::string, native_function> methods;
public:
template <typename F, F fn>
class_ &method(const std::string &name) {
methods[name] = method_helper<C, F>::template toNative<fn>();
return *this;
}
};
允许:
class_<MyClass>()
.method<decltype(&MyClass::numRows), &MyClass::numRows>("numRows");
但是,我还想允许将非成员函数作为方法添加到导出的类中。问题是我需要一个不同的method
定义来处理普通的函数指针:
template <F, F fn>
class_ &method(const std::string &name) {
methods[name] = function_helper<F>::template toNative<fn>();
return *this;
}
但是,如上所示,模板参数将完全相同。
除了创建一个名称完全不同的函数外,是否有方便的方法来区分函数指针和成员函数指针?或者有没有办法在运行时确定要运行的代码?
答案 0 :(得分:2)
使用SFINAE:
template<
typename F
, F fn
, typename std::enable_if<
std::is_member_pointer<F>::value
, int
>::type...
>
class_ &method(const std::string &name)
{
methods[name] = method_helper<C, F>::template toNative<fn>();
return *this;
}
template<
typename F
, F fn
, typename std::enable_if<
!std::is_member_pointer<F>::value
, int
>::type...
>
class_ &method(const std::string &name)
{
methods[name] = function_helper<F>::template toNative<fn>();
return *this;
}
答案 1 :(得分:0)
示例中的非成员函数指针将具有签名:
template<typename Ret, typename Args...> Ret (*)(Args args...)
和一个成员函数指针签名:
template<typename Ret, typename Args...> Ret (C::*)(Args args...)
这使您可以专注于两个签名:
template <typename F, F fn>
class_ &method(const std::string &name) { return method_impl(name, fn); }
template <typename F>
class_ &method_impl(const std::string &name, F fn)
{
// non-member function variant.
}
template <typename Ret, typename Args...>
class_ &method_impl(const std::string &name, Ret (C::*fn)(Args args...))
{
// member function variant.
}
注意:如果您将method_impl
更改为method
,则可以简化API,允许:
class_<MyClass>().method("numRows", &MyClass::numRows);