区分函数指针和成员函数指针

时间:2012-10-12 22:13:51

标签: c++ c++11 function-pointers wrapping member-function-pointers

我这段代码似乎有效:

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

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

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

2 个答案:

答案 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);