[英]Cast reference to pointer in function pointer return value
Emscripten生成用于从JavaScript调用C ++函数的自动绑定。 但是,如果函数返回引用,则结果将按值传递给JavaScript。 指针返回值通过引用传递。 因此,如果我有一个功能:
MyType &MyClass::doStuff(int x,int y);
我可以做类似的事情:
function("doStuff",&MyClass::doStuff);
使它出现在JavaScript中。 但是我需要的是:
function("doStuff",reinterpret_cast<MyType *(MyClass::*)(int,int)>(&doStuff));
使它返回一个指针。 但是对于每个函数来说都很难键入,所以我需要一个魔术宏来转换:
function("doStuff",MAGIC(MyClass::doStuff));
转换为上述版本(适用于采用任意数量的任何类型的参数的函数),并带有强制转换或类似功能。 问题是:这在C ++ 11中可能吗?
在函数指针(或成员函数指针)上执行reinterpret_cast
是一个严重的坏主意。
而是编写一个适配器:
template<typename M, M m> struct make_wrapper_helper;
template<typename T, typename R, typename... A, R& (T::*m)(A...)>
struct make_wrapper_helper<R& (T::*)(A...), m> {
R* (*operator()())(T&, A...) {
return [](T& t, A ...a) -> R* { return &(t.*m)(static_cast<A>(a)...); };
}
};
template<typename M, M m>
decltype(make_wrapper_helper<M, m>()()) make_wrapper() {
return make_wrapper_helper<M, m>()();
}
function("doStuff", make_wrapper<decltype(&MyClass::doStuff), &MyClass::doStuff>())
不幸的是,由于lambda必须是不可捕获的,因此成员函数指针必须作为非类型模板参数传递,这意味着无法推导它。 您可以使用宏来解决此问题。
ecatmur完美地回答了这个问题,但是花了我一些时间来理解代码的实际作用,因此下面是使用宏的注释版本:
// Helper type for PTR_RETURN() macro.
template<typename RetTypeRef, RetTypeRef method> struct ptrReturnHelper;
// Specialize the helper for a particular class, method and set of arguments.
template<
typename Class,
typename RetType,
typename... ArgType,
RetType &(Class::*method)(ArgType...)
> struct ptrReturnHelper<RetType &(Class::*)(ArgType...), method> {
/* Function returning function pointer,
called inside EMSCRIPTEN_BINDINGS block. */
auto getWrapper()->auto(*)(Class &, ArgType...)->RetType * {
/* PTR_RETURN() macro ultimately returns this lambda function which
converts the original function pointer return value: */
return [](Class &obj, ArgType ...arg) -> RetType * {
return &(obj.*method)(static_cast<ArgType>(arg)...);
};
}
};
/* Convert a pointer to RetType &Class::method(ArgType...)
into a pointer to RetType *Class::method(ArgType...) */
#define PTR_RETURN(method) \
(ptrReturnHelper<decltype(method),method>().getWrapper())
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.