将引用强制转换为函数指针返回值中的指针
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())
相关文章:
- 将返回值存储在函数指针数组的指针中是如何工作的?
- 当我使用 void 函数的返回值(通过强制转换函数指针)时,究竟会发生什么?
- 如何读取指针的值,因为这个指针是函数的返回?
- 如何在不使用临时变量的情况下取消引用返回指针的函数的返回值?
- 如何返回值为NULL的变量指针
- 将指向数组的指针作为函数参数传递,这本身就是另一个函数的返回值?
- 存储指向函数返回值的指针
- 指针未正确返回值
- 动态指针引用数组由三元运算符返回值,但有异常
- 指针返回值的地址
- 此指针 - 按值返回 vs 按引用返回
- 将指针设置为函数的返回值
- (C )当在同一类中调用时,污点指针返回正确的值,而从MAIN调用时为0
- 即使在返回值之前释放后,数据仍在指针中仍然存在
- 返回指针、返回值或传入引用,这在C++中很优雅
- 为什么指针返回值,而不是地址
- 字符指针返回值垃圾
- 将引用强制转换为函数指针返回值中的指针
- 为什么指针返回值而不是地址
- 函数指针返回值时出现奇怪的seg错误