Проблема
Имейте шаблон, который генерирует оболочку для произвольной функции-члена, которая позволяет вызывать эту функцию для объекта, например:
Для заданного bool std::string::empty()
создается оболочка bool wrapper(const std::string& str) { return str.empty(); }
.
Функция-оболочка не должна быть лямбда-выражением (чтобы ее можно было передать как указатель на функцию).
Мой подход (для неконстантных функций-членов)
/* Wrapper (for non-const member functions) */
template<typename T, typename R, typename... ARGS>
struct staticWrapperHelper
{
using fType = R (T::*)(ARGS...);
template<fType FUNCTION>
static R wrapper(T& object, ARGS... args) { return object.*FUNCTION(args...); }
};
template<typename T, typename R, typename... ARGS>
auto staticWrapper(R (T::*memberFunction)(ARGS...))
{
//auto function = [memberFunction] (T& object, ARGS... args) -> R { return (object.*memberFunction)(args...); };
using Helper = staticWrapperHelper<T, R, ARGS...>;
R (*wrapper)(T&, ARGS...) = &Helper::template wrapper<R (T::*)(ARGS...)>;
return wrapper;
}
/* Example */
class A
{
public:
void member() {}
};
int main()
{
A a;
auto f = staticWrapper<A>(&A::member);
f(a);
return 0;
}
Проблема с моим подходом
Он не компилируется. Похоже, что возвращенная оболочка все еще является шаблоном: http://coliru.stacked-crooked.com/a/d4c0dd9ab631aa1f
g++ -std=c++14 -O2 -Wall -pedantic -pthread main.cpp && ./a.out main.cpp: In instantiation of 'auto staticWrapper(R (T::*)(ARGS ...)) [with T = A; R = void; ARGS = {}]': main.cpp:32:41: required from here main.cpp:17:9: error: no matches converting function 'wrapper' to type 'void (*)(class A&)' 17 | R (*wrapper)(T&, ARGS...) = &Helper::template wrapper; | ^~~~~~~ main.cpp:8:14: note: candidate is: 'template static R staticWrapperHelper::wrapper(T&, ARGS ...) [with R (T::* FUNCTION)(ARGS ...) = FUNCTION; T = A; R = void; ARGS = {}]' 8 | static R wrapper(T& object, ARGS... args) { return object.*FUNCTION(args...); } | ^~~~~~~
Любые идеи?
Helper::template wrapper<memberFunction>
вместоHelper::template wrapper<R (T::*)(ARGS...)>
; и да, посколькуmemberFunction
- это аргумент функции, я не могу использовать его здесь как параметр шаблона дляstaticWrapperHelper
, хотя в общем случае указатели на функции могут быть параметрами шаблона. 11.02.2020staticWrapper
функциейconstexpr
, но я не уверен, что это может быть решением или нет. 12.02.2020constexpr
функцию. 14.02.2020