我正在尝试构建一个静态包装函数,它可以调用成员和非成员函数指针。
我想出的是如下 -
template <typename Derived>
struct CallAny {
template<typename F> using ReturnType = typename std::function<typename std::remove_pointer<F>::type>::result_type;
template<typename F, bool IsMember, typename... Args>
static ReturnType<F> function_wrapper(Derived* obj, F func, Args... args);
template<typename F, typename... Args>
static ReturnType<F> function_wrapper<F, true, Args...>(Derived *obj, F func, Args... args) {
return obj->*func(args...);
}
template<typename F, typename... Args>
static ReturnType<F> function_wrapper<F, false, Args...>(Derived *obj, F func, Args... args) {
return func(args...);
}
};
struct CallAnyDerived : public CallAny<CallAnyDerived> {};
这里F
是一个函数指针类型,必须使用Args...
中给出的参数调用。 F
可能是C风格的函数指针或继承自Derived
的类CallAny
的成员。
当我尝试编译此代码时,我收到错误消息 -
XXXXXXXXXXX: error: function template partial specialization ‘fucntion_wrapper<F, true, Args ...>’ is not allowed
static ReturnType<F> function_wrapper<F, true, Args...>(Derived *obj, F func, Args... args) {
^
XXXXXXXXXXX: error: function template partial specialization ‘fucntion_wrapper<F, false, Args ...>’ is not allowed
static ReturnType<F> function_wrapper<F, false, Args...>(Derived *obj, F func, Args... args) {
^
我该如何解决这个问题?
答案 0 :(得分:4)
通常,您不能部分专门化功能。解决这个问题的方法是创建一个类似static R call(...)
之类的辅助结构,并部分地专门化辅助结构。
在这种情况下,您根本不需要模板专业化,您可以使用重载
template <typename Derived>
struct CallAny {
template<typename F> using ReturnType = typename std::function<typename std::remove_pointer<F>::type>::result_type;
// takes pointer to member function
template<typename R, typename... Ts, typename... Args>
static R function_wrapper(Derived* obj, R (Derived::*func)(Ts...), Args... args) {
return obj->*func(args...);
}
// takes everything else
template<typename F, typename... Args>
static ReturnType<F> function_wrapper(Derived *obj, F func, Args... args) {
return func(args...);
}
};
答案 1 :(得分:1)
您可以使用SFINAE:
template <typename Derived>
struct CallAny {
template<typename F, typename... Args>
static
auto
function_wrapper(Derived* obj, F func, Args&&... args)
-> std::enable_if_t<
std::is_member_function_pointer<F>::value,
decltype((obj->func)(std::forward<Args>(args)...))>
{
return (obj->func)(std::forward<Args>(args)...);
}
template<typename F, typename... Args>
static
auto
function_wrapper(Derived* obj, F func, Args&&... args)
-> std::enable_if_t<
!std::is_member_function_pointer<F>::value,
decltype(func)(/*obj,*/std::forward<Args>(args)...))>
{
return func(/*obj,*/std::forward<Args>(args)...);
}
};
或标签调度:
template <typename Derived>
struct CallAny {
template<typename F, typename... Args>
static
auto
function_wrapper(Derived* obj, F func, Args&&... args)
{
return impl(std::is_member_function_pointer<F>{}, obj, func, std::forward<Args>(args)...);
}
template<typename F, typename... Args>
static
auto
impl(std::true_type, Derived* obj, F func, Args&&... args)
-> decltype((obj->func)(std::forward<Args>(args)...))
{
return (obj->func)(std::forward<Args>(args)...);
}
template<typename F, typename... Args>
static
auto
impl(std::true_type, Derived* obj, F func, Args&&... args)
-> decltype(func)(/*obj,*/std::forward<Args>(args)...))>
{
return func(/*obj,*/std::forward<Args>(args)...);
}
};