1

我这个代码,它似乎工作:

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;
}

但是,如上所示,模板参数将完全相同。

除了创建一个名称完全不同的函数之外,还有没有方便的方法来区分函数指针和成员函数指针?或者有没有办法在运行时确定要运行哪些代码?

4

2 回答 2

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;
}
于 2012-10-13T00:27:58.600 回答
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_implmethod,您可以简化您的 API,允许:

class_<MyClass>().method("numRows", &MyClass::numRows);
于 2012-10-12T22:39:44.600 回答