将成员函数转发给静态方法

atl*_*ste 6 c++ function-pointers member-functions c++11

上下文

基本上,我需要有const void *const一个成员函数,因为这将被传递到第三方库(这意味着我不能使用bind,function等等).由于这似乎是不可能的,我想做下一个最好的事情并将成员函数映射到静态转发方法,然后我可以获取指针(this作为第一个参数传递).

我有很多需要注册的函数,具有不同的签名,所以我想有一个很好的解决方案,允许我将成员函数的签名转换为静态方法签名(this当然作为参数传递) -然后,我可以投入到const void* const.所以基本上我想做这样的事情:

所以基本上:

struct Foo
{ 
    MyType Bar(int a);
};

template <typename Ret, typename This, Ret(This::*Func)()>
struct CallWrap0
{
    static Ret &&Call(This* thisPtr)
    {
        return thisPtr->(*Func)();
    }
};

int Main()
{
    const void * const memberFunction = &(CallWrap0<MyType, Foo, Foo::Bar>()::Call);
    // etc.
}
Run Code Online (Sandbox Code Playgroud)

这个解决方案的问题在于 - 尽管它有效 - 但它不是很好,因为我必须明确地告诉编译器类型.我正在寻找一种解决方案,编译器可以自动填充所有管道.

我一直试图用辅助函数解决这个问题,到目前为止没有运气:

template <class Ret, class T, class... Args>
const void* const FunctionPtr(Ret (T::*function)(Args... args))
{
    // not sure... function is not a template, so this would require a class instance
    // which is not possible due to the ext. library constraints.
}
Run Code Online (Sandbox Code Playgroud)

Pio*_*cki 4

#include <utility>

template <typename T, T t>
struct CallWrap;

template <typename Ret, typename This, typename... Args, Ret(This::*Func)(Args...)>
struct CallWrap<Ret(This::*)(Args...), Func>
{
    static Ret Call(This* thisPtr, Args... args)
    {
        return (thisPtr->*Func)(std::forward<Args>(args)...);
    }
};

int main()
{
    auto f = &CallWrap<decltype(&Foo::Bar), &Foo::Bar>::Call;
}
Run Code Online (Sandbox Code Playgroud)

演示版


对于无法编译上述解决方案的MSVC,请尝试以下代码:

template <typename T>
struct CallWrap;

template <typename Ret, typename This, typename... Args>
struct CallWrap<Ret(This::*)(Args...)>
{
    template <Ret(This::*Func)(Args...)>
    struct Function
    {
        static Ret Call(This* thisPtr, Args... args)
        {
            return (thisPtr->*Func)(std::forward<Args>(args)...);
        }
    };
};

int main()
{
    auto f = &CallWrap<decltype(&Foo::Bar)>::Function<&Foo::Bar>::Call;
}
Run Code Online (Sandbox Code Playgroud)

演示2

  • MSVC 2015 确实编译了第一个演示,在 http://webcompiler.cloudapp.net/ 上进行了测试 (2认同)