I'm writing a simple "wrapper library" around another library and I'm having issues with std::function not being able to deduce template arguments for variadic template functions. To make things more concrete:
There's a library (it's a HTTP server) that I'm planning to "expand" with more functionality and to make it more convenient to use by "other code users" (automatic serialization of data, writing controller functions based on needs etc.). Basically cutting down on a lot of boilerplate code. From now on I'm calling this one simply "library". It cannot be touched or changed.
There's the code that "expands" the functionality above that I write myself and it's where I have the problem. From now on I call this a "wrapper library".
There's the "user code", that is - any code that uses the "wrapper library". I've included examples what I'd like it to look like and I'd rather keep it as simple as possible, especially when it comes to unnecessary template parameters bloat (not having to explicitly pass template arguments when it can be deduced by the compiler etc.). See main in the code below for examples.
Here's the complete example (that doesn't compile):
#include <type_traits>
#include <variant>
#include <vector>
/*** Library code starts here ***/
// Library handler function definition to be registered. This cannot be changed.
// For simplicity I made the function arguments (int, int) to denote that this
// handler function does take some arguments passed later by the library.
// In reality these are simple, non-templated structs.
using LibraryHandler = std::function<void(int, int)>;
std::vector<LibraryHandler> g_libraryHandlers;
void RegisterLibraryHandler(LibraryHandler handler)
{
// Library code registering passed handler. This cannot be changed.
g_libraryHandlers.push_back(handler);
}
/*** End of library code ***/
/*** My "wrapper library" starts here ***/
// ReturnType is the type returned by the functions written by "wrapper library users".
// Types... is the list of all possible types held by 'ReturnType' that a given function is allowed to return.
template<typename T, typename... Types>
static inline constexpr bool isConstructible = (std::is_constructible_v<T, Types> || ...);
template<typename T, typename... Types>
static inline constexpr bool isAssignable = (std::is_assignable_v<T&, Types> || ...);
template<typename... Types>
class ReturnType
{
public:
template<typename T, std::enable_if_t<
isConstructible<T, Types...> &&
isAssignable<T, Types...>,
int> = 0>
static ReturnType Build(const T& data)
{
return ReturnType(data);
}
private:
template<typename T>
ReturnType(const T& data) : m_data(data) { }
std::variant<Types...> m_data;
};
template<typename T>
class ParamType
{
public:
ParamType() { }
const T& GetData() const { return m_data; }
private:
T m_data;
};
/*** This is where my problem is - how to write these functions to allow for
different logic (based on passed function signature) inside nested lambda? ***/
// Version registering functions taking no arguments
template<typename... Types>
void RegisterFunction(std::function<ReturnType<Types...>()> func)
{
auto wrapperLambda = [func](int a, int b) { // Construct lambda to conform with library interface ('LibraryHandler')
// Logic specific for 'func' with signature: ReturnType<Types...>() - step before call
func();
// Logic specific for 'func' with signature: ReturnType<Types...>() - step after call
};
RegisterLibraryHandler(wrapperLambda); // Register lambda inside library
}
// Version registering functions taking arguments through 'ParamType'
template<typename... Types, typename TParam>
void RegisterFunction(std::function<ReturnType<Types...>(const ParamType<TParam>)> func)
{
auto wrapperLambda = [func](int a, int b) { // Construct lambda to conform with library interface ('LibraryHandler')
// Logic specific for 'func' with signature: ReturnType<Types...>(const ParamType<TParam>) - step before call
func();
// Logic specific for 'func' with signature: ReturnType<Types...>(const ParamType<TParam>) - step after call
};
RegisterLibraryHandler(wrapperLambda); // Register lambda inside library
}
// Version registering functions taking library arguments directly
template<typename... Types, typename TParam>
void RegisterFunction(std::function<ReturnType<Types...>(int, int)> func)
{
auto wrapperLambda = [func](int a, int b) { // Construct lambda to conform with library interface ('LibraryHandler')
// Logic specific for 'func' with signature: ReturnType<Types...>(int, int) - step before call
func(a, b);
// Logic specific for 'func' with signature: ReturnType<Types...>(int, int) - step after call
};
RegisterLibraryHandler(wrapperLambda); // Register lambda inside library
}
/*** End of my "wrapper library" ***/
/*** This is how I'd like the "users of the wrapper library" to write the code ***/
struct SomeReturnData { char a; char b; };
struct OtherReturnData { char c; char d; };
struct SomeParameterType { int p; };
// Example 1 - function only ever returning a single type, taking no arguments
ReturnType<SomeReturnData> UserFunctionNoArgs()
{
SomeReturnData data{ 'x', 'y' };
return ReturnType<SomeReturnData>::Build(data);
}
// Example 2 - function taking parameter 'SomeParameterType' and returning 'SomeReturnData' or 'OtherReturnData'
// based on contents of passed argument.
ReturnType<SomeReturnData, OtherReturnData> UserFunctionArgs(const ParamType<SomeParameterType> param)
{
if (param.GetData().p == 1000)
return ReturnType<SomeReturnData, OtherReturnData>::Build(SomeReturnData());
return ReturnType<SomeReturnData, OtherReturnData>::Build(OtherReturnData());
}
// Example 3 - function requesting library arguments to be passed directly
ReturnType<SomeReturnData, OtherReturnData> UserHandlingLibraryDirectly(int libraryArg1, int libraryArg2)
{
if (libraryArg1 == libraryArg2)
return ReturnType<SomeReturnData, OtherReturnData>::Build(SomeReturnData());
return ReturnType<SomeReturnData, OtherReturnData>::Build(OtherReturnData());
}
int main()
{
// User registers written functions in the "wrapper library".
// This includes any 'regluar functions'...
RegisterFunction(UserFunctionNoArgs);
RegisterFunction(UserFunctionArgs);
RegisterFunction(UserHandlingLibraryDirectly);
// ... or lambdas with captures (all possible parameter combinations from examples above apply).
int someInt = 123;
auto userLambda = [someInt]() -> ReturnType<SomeReturnData, OtherReturnData> {
if(someInt < 100)
return ReturnType<SomeReturnData, OtherReturnData>::Build(SomeReturnData());
return ReturnType<SomeReturnData, OtherReturnData>::Build(OtherReturnData());
};
return 0;
}
My issue is with the RegisterFunction above - I'd basically want to write it the way it is above, which is obviously not possible (the compiler complains about not being able to deduce template parameters). My goal is to not change / cut down on possibilities / make any more complicated anything that's inside main.
Lambdas are not std::function, so cannot be deduced. Fortunately, std::function has CTAD (c++17) allowing to solve your issue with an extra overload:
template<typename Func>
void RegisterFunction(Func func)
{
RegisterFunction(std::function{func}); // forward to overload taking std::function
}
Demo
Related
As I understand, typedef cannot be used for overloading but what if I need to use some different types as arguments to the function pointer?
How can I make it work with the following functionality?
{
public:
typedef void (*InitFunc)(float x);
typedef void (*InitFunc)(int a, char b); //Needs to be added
virtual void initialize(InitFunc init) = 0;
};
Edit:
I cannot use C++17, so can't use variant
As commented, the easiest way is a union, although not very type safe and C++-y. Here is an example with inheritance, since you commented that you want inheritance.
typedef void (*FloatInit)(float x);
typedef void (*IntCharInit)(int a, char b);
union InitFn {
FloatInit fi;
IntCharInit ici;
};
struct Foo {
void initialize(InitFn) = 0;
};
struct FloatFoo: public Foo {
void initialize(InitFn f) override {
f.fi(42.0f);
}
};
void test(float) {}
// ...
auto x = FloatFoo{};
x.initialize(InitFn{test});
As mentioned by other commenters, you can use std::variant to enhance type safety and get rid of the manual union definition:
typedef void (*FloatInit)(float x);
typedef void (*IntCharInit)(int a, char b);
typedef std::variant<FloatInit, IntCharInit> InitFn;
struct Foo {
void initialize(InitFn) = 0;
};
struct FloatFoo: public Foo {
void initialize(InitFn f) override {
std::get<FloatInit>(f)(42.0f);
}
};
void test(float) {}
// ...
auto x = FloatFoo{};
x.initialize(InitFn{test});
One solution is to create a simple wrapper class template instead, to allow the compiler to automatically generate instantiations as necessary. This is relatively simple if init is always guaranteed to be a non-member function (and by extension, an actual function and not a functor/lambda).
// Quick-and-dirty transparent callable wrapper, to serve as overloadable "type alias".
template<typename>
class InitFunc;
template<typename Ret, typename... Params>
class InitFunc<Ret(*)(Params...)> {
public:
// Supply component types if needed.
// Tuple used for params, for convenience.
using return_type = Ret;
using param_types = std::tuple<Params...>;
using func_type = Ret(Params...);
using func_ptr_type = func_type*;
using func_ref_type = func_type&;
// Create from pointer or reference.
constexpr InitFunc(func_ptr_type p = nullptr) : ptr(p) {}
constexpr InitFunc(func_ref_type r) : ptr(&r) {}
// Transparent invocation.
// Deduces argument types instead of relying on Params, to allow for perfect forwarding.
template<typename... Ts>
constexpr return_type operator()(Ts&&... ts) { return ptr(std::forward<Ts>(ts)...); }
// Convert back to original type if necessary.
operator func_ptr_type() { return ptr; }
operator func_ref_type() { return *ptr; }
private:
// Actual function pointer.
func_ptr_type ptr;
};
// And a nice, clean creator, which can be renamed as necessary.
template<typename Init>
constexpr auto make(Init func) { return InitFunc<Init>(func); }
This creates a nice little wrapper that can easily be optimised out entirely, and will compile as long as C++14 support is available.
Note that you require a C++11 compiler (or variadic templates, rvalue references, perfect forwarding, and constexpr support) at the absolute minimum, and will need to modify make() to have a trailing return type for pre-C++14 compilers. I believe this is compatible with C++11 constexpr, but I'm not 100% sure.
If you want InitFunc to be able to accept pointers/references-to-member-function (including functors and lambdas), you'll need to provide an additional version to isolate it into a non-member "function", and likely bind it to a class instance. It may be worth looking into std::bind() in this case, although I'm not sure if it has any overhead.
In this case, I would suggest splitting the member types off into a base class, to reduce the amount of code you'll need to duplicate.
// Quick-and-dirty transparent callable wrapper, to serve as overloadable "type alias".
template<typename>
class InitFunc;
// Supply component types if needed.
// Tuple used for params, for convenience.
// Using actual function type as a base, similar to std::function.
template<typename Ret, typename... Params>
class InitFunc<Ret(Params...)> {
public:
using return_type = Ret;
using param_types = std::tuple<Params...>;
using func_type = Ret(Params...);
using func_ptr_type = func_type*;
using func_ref_type = func_type&;
};
// Non-member functions.
// As member types are now dependent types, we qualify them and use `typename`.
// Yes, it looks just as silly as you think it does.
template<typename Ret, typename... Params>
class InitFunc<Ret(*)(Params...)> : public InitFunc<Ret(Params...)> {
// Actual function pointer.
typename InitFunc::func_ptr_type ptr;
public:
// Create from pointer or reference.
constexpr InitFunc(typename InitFunc::func_ptr_type p = nullptr) : ptr(p) {}
constexpr InitFunc(typename InitFunc::func_ref_type r) : ptr(&r) {}
// Transparent invocation.
// Deduces argument types instead of relying on Params, to allow for perfect forwarding.
template<typename... Ts>
constexpr typename InitFunc::return_type operator()(Ts&&... ts) { return ptr(std::forward<Ts>(ts)...); }
// Convert back to original type if necessary.
operator typename InitFunc::func_ptr_type() { return ptr; }
operator typename InitFunc::func_ref_type() { return *ptr; }
};
// See ecatmur's http://stackoverflow.com/a/13359520/5386374 for how to accomodate member functions.
// ...
// Non-member function make() is unaffected.
// An overload will likely be needed for member functions.
template<typename Init>
auto make(Init func) { return InitFunc<Init>(func); }
Despite the awkwardness inside our derived specialisation, any code that relies on InitFunc shouldn't (to my knowledge) see any changes to its API; the previous example will work just fine if we swap to this new InitFunc, and be none the wiser after recompilation.
Note that it will change the ABI, though, and thus any code compiled for the simpler InitFunc will need to be recompiled for this version.
I try to understand how https://github.com/tomaka/luawrapper works and
extracted one codepath from it. I simplified it to understand it and
came up with the below code.
What puzzles me is the way struct Binder works and how readIntoFunction() creates the binder function objects in advance of it being used, leading to the creation of a call to the lambda that was supplied at the beginning.
Question now:
I had real problems getting my head around this piece of code. Is it just me that thinks this code is hilarious?
Is there some easier way to achieve the same thing? Is there some easier way to generate a binder function from the type signature of the lambda supplied?
g++ -g -std=c++14 test.cpp -o test.exe
test.cpp:
#include <stdio.h>
#include <iostream>
#include <stdlib.h>
#include <functional>
template<typename T> struct tag {};
template<typename TFunctionObject, typename TFirstParamType>
struct Binder {
TFunctionObject function;
TFirstParamType param;
template<typename... TParams>
auto operator()(TParams&&... params) -> decltype(function(param, std::forward<TParams>(params)...)) {
return function(param, std::forward<TParams>(params)...);
}
};
class A {
public:
int a[3];
/* trigger the actual call */
template<typename TCallback>
static int readIntoFunction(TCallback&& callback, A &c, int ) {
return callback();
}
/* at the first call 'callback' is the lambda supplied to
A::ca() at the beginning. Each iteration will generate a
derived call object with one argument less than 'callback' */
template<typename TCallback, typename TFirstType, typename... TTypes>
static int readIntoFunction(TCallback&& callback, A &c, int index, tag<TFirstType>, tag<TTypes>... othersTags)
{
const TFirstType v = c.a[index];
Binder<TCallback, const TFirstType&> binder{ callback, v };
return readIntoFunction(binder, c, index + 1, othersTags...);
}
template<typename TType, typename = void>
struct Split {
template<typename TType2>
static void push(A &c, TType2 value) {
}
};
/* with template packs ready, call readIntoFunction().
the 'value' parameter is the target lambda function to
call */
template<typename TReturnType, typename... TParameters>
struct Split<TReturnType (TParameters...)>
{
template<typename TFunctionObject>
static void push(A &c, TFunctionObject value) noexcept {
A::readIntoFunction(value, c, 0, tag<TParameters>{}...);
}
};
/* split up the function signature into return/parameters,
specialize from (*)() to (). */
template<typename TReturnType, typename... TParameters>
struct Split<TReturnType (*)(TParameters...)>
{
typedef Split<TReturnType(TParameters...)> SubPusher;
template<typename TType>
static void push(A &c, TType value) noexcept {
SubPusher::push(c, value);
}
};
/* entry, called with a lambda function as argument */
template<typename TFunctionType>
auto ca(TFunctionType&& data) {
typedef typename std::decay<TFunctionType>::type RealDataType;
Split<RealDataType>::push(*this, std::forward<TFunctionType>(data));
}
};
int main(int argc, char **argv) {
A c{{ 1, 2, 3}};
c.ca( (int (*)(int,float))[](int a,float b)->int {
std::cout << a << b << std::endl;
});
c.ca( (int (*)(int,float,double))[](int a,float b,double c)->int {
std::cout << a << b << c << std::endl;
});
}
Is there some easier way to generate a binder function from the type signature of the lambda supplied?
The short answer is “No”.
Generally, you could use standard library equivalents, std::function, std::bind, std::placeholders. The implementation code is even more complex. But they're in the standard library, i.e. you don’t have to support that code, and you’ll get documentation.
For this particular case, however, they won’t work. Because the function doesn’t just make a callable thing like std::function, instead it marshals the arguments + return value to LUA.
Other methods exist, but they aren’t necessarily simpler. Sometimes C #defines leads to simpler code. In other cases, external scripts or tools running in a pre-build step generate the boilerplate code from something else (special comments/other markup in your source, or external LUA code, or external protocol/interface definitions).
Generally, to write code like this, reflection support in the programming language helps. Unfortunately, C++ has no reflection. Hence that write-only template code.
I've been trying to come up with a templated function that generalizes the bounce procedure when dealing with C APIs that use function pointer callbacks.
I've mostly figured it out and have a working system, but I'm wondering if there is a way to clean up the final step.
Imagine you have an API that takes a function pointer and a user data pointer. You want to use an instance method as the callback target. This requires a "bounce" function that reinterprets the user data pointer as an instance pointer and calls the method with the rest of the arguments.
The following example code works:
#include <cstdio>
class Foo {
public:
Foo(int val) : val_(val) { }
void baz(int v) const
{
printf("baz %d\n", v + val_);
}
private:
int val_;
};
// Templated bounce function
template<class T, class Method, Method m, class Ret, class ...Args>
static Ret bounce(void *priv, Args... args)
{
return ((*reinterpret_cast<T *>(priv)).*m)(args...);
}
#define BOUNCE(c, m) bounce<c, decltype(&c::m), &c::m>
// Callback simulator
void call_callback(void (*func)(void *, int), void *priv, int v)
{
if (func) {
func(priv, v);
}
}
// Main Entry
int main()
{
Foo bar(13);
call_callback(&bounce<Foo, decltype(&Foo::baz), &Foo::baz>, &bar, 10);
call_callback(&BOUNCE(Foo, baz), &bar, 11);
return 0;
}
Basically I'm looking for a way to clean up the usage. The macro works but I'm trying to instead find some type of helper function that can just take a method pointer parameter like &Foo::baz and deduce all the parameters. Something like a bounce_gen(&Foo::baz) that would return a pointer to the actual bounce function.
It has been a fun exercise, but I can't quite get the last piece.
The type of a member function pointer contains the class type and the function signature. So, you can let template function argument deduction handle this for you:
template<class T, class Method, class ...Args>
static auto bounce(Method T::*func, T* priv, Args... args) -> decltype((priv->*m)(args...))
{
return (priv->*m)(args...);
}
More convenient might be to either use std::bind or a lambda to completely hide the fact that it is a member function call:
template<class Func, class ...Args>
static auto bounceCallable(Func func, Args... args) -> decltype(func(args...))
{
return func(args...);
}
And you would call it like this:
call_callback([&bar](int v){bar.baz(v);}, 11);
With a lambda, you have a syntax nicer than with std::bind, but it comes at the cost of having to repeat the signature.
Say I'm using a C API that lets you register callbacks that take a void* closure:
void register_callback(void (*func)(void*), void *closure);
In C++ it's nice to have stronger types than void* so I want to create a wrapper that lets me register strongly-typed C++ callbacks instead:
template <typename T, void F(T*)>
void CallbackWrapper(void *p) {
return F(static_cast<T*>(p));
}
void MyCallback(int* param) {}
void f(void *closure) {
register_callback(CallbackWrapper<int, MyCallback>, closure);
}
This works alright. One nice property of this solution is that it can inline my callback into the wrapper, so this wrapping scheme has zero overhead. I consider this a requirement.
But it would be nice if I could make the API look more like this:
void f2() {
RegisterCallback(MyCallback, closure);
}
I hope I can achieve the above by inferring template parameters. But I can't quite figure out how to make it work. My attempt so far is:
template <typename T>
void RegisterCallback(void (*f)(T*), T* closure) {
register_callback(CallbackWrapper<T, f>, closure);
}
But this doesn't work. Anyone have a magic incantation that will make f2() work above, while retaining the zero-overhead performance characteristic? I want something that will work in C++98.
This template function improves the syntax marginally.
template <typename T, void F(T*)>
void RegisterCallback (T *x) {
register_callback(CallbackWrapper<T, F>, x);
}
int x = 4;
RegisterCallback<int, MyCallback>(&x);
If you are willing to use a functor rather than a function to define your callback, then you can simplify things a bit more:
#ifdef HAS_EXCEPTIONS
# define BEGIN_TRY try {
# define END_TRY } catch (...) {}
#else
# define BEGIN_TRY
# define END_TRY
#endif
template <typename CB>
void CallbackWrapper(void *p) {
BEGIN_TRY
return (*static_cast<CB*>(p))();
END_TRY
}
struct MyCallback {
MyCallback () {}
void operator () () {}
};
template <typename CB>
void RegisterCallback (CB &x) {
register_callback(CallbackWrapper<CB>, &x);
}
MyCallback cb;
RegisterCallback(cb);
But, as others have mentioned, you run the risk of the code not porting correctly to a system where the C ABI and C++ ABI differ.
I have discovered a better answer to this question than the other answers given to me here! (Actually it was another engineer inside Google who suggested it).
You have to repeat the function name twice, but that can be solved with a macro.
The basic pattern is:
// Func1, Func2, Func3: Template classes representing a function and its
// signature.
//
// Since the function is a template parameter, calling the function can be
// inlined at compile-time and does not require a function pointer at runtime.
// These functions are not bound to a handler data so have no data or cleanup
// handler.
template <class R, class P1, R F(P1)>
struct Func1 {
typedef R Return;
static R Call(P1 p1) { return F(p1); }
};
// ...
// FuncSig1, FuncSig2, FuncSig3: template classes reflecting a function
// *signature*, but without a specific function attached.
//
// These classes contain member functions that can be invoked with a
// specific function to return a Func/BoundFunc class.
template <class R, class P1>
struct FuncSig1 {
template <R F(P1)>
Func1<R, P1, F> GetFunc() { return Func1<R, P1, F>(); }
};
// ...
// Overloaded template function that can construct the appropriate FuncSig*
// class given a function pointer by deducing the template parameters.
template <class R, class P1>
inline FuncSig1<R, P1> MatchFunc(R (*f)(P1)) {
(void)f; // Only used for template parameter deduction.
return FuncSig1<R, P1>();
}
// ...
// Function that casts the first parameter to the given type.
template <class R, class P1, R F(P1)>
R CastArgument(void *c) {
return F(static_cast<P1>(c));
}
template <class F>
struct WrappedFunc;
template <class R, class P1, R F(P1)>
struct WrappedFunc<Func1<R, P1, F> > {
typedef Func1<R, void*, CastArgument<R, P1, F> > Func;
};
template <class T>
generic_func_t *GetWrappedFuncPtr(T func) {
typedef typename WrappedFunc<T>::Func Func;
return Func().Call;
}
// User code:
#include <iostream>
typedef void (generic_func_t)(void*);
void StronglyTypedFunc(int *x) {
std::cout << "value: " << *x << "\n";
}
int main() {
generic_func_t *f = GetWrappedFuncPtr(
MatchFunc(StronglyTypedFunc).GetFunc<StronglyTypedFunc>());
int x = 5;
f(&x);
}
This is not short or simple, but it is correct, principled, and standard-compliant!
It gets me what I want:
The user gets to write StronglyTypedFunc() taking a pointer to a specific thing.
This function can be called with a void* argument.
There is no virtual function overhead or indirection.
Why not make your closure a real closure (by including real typed state).
class CB
{
public:
virtual ~CB() {}
virtual void action() = 0;
};
extern "C" void CInterface(void* data)
{
try
{
reinterpret_cast<CB*>(data)->action();
}
catch(...){}
// No gurantees about throwing exceptions across a C ABI.
// So you need to catch all exceptions and drop them
// Or probably log them
}
void RegisterAction(CB& action)
{
register_callback(CInterface, &action);
}
By using an object you can introduce real state.
You have a clean C++ interface with correctly types objects.
Its easy to use you just derive from CB and implement action().
This also has the same number of actual function calls as you use. Because in your example you pass a function pointer to the wrapper (which can't be inlined (it can but it will take more static analysis then current compilers do)).
Apparently it does inline.
I am trying to simplify (via make_fn()) the generation of functors that preprocess parameters (via wrap()) for member functions of arity n.
Generating the functors is basically working, but until now only by explicitly specifying the parameter types for the member function.
Now i'd like to generate the correct functor from the member function type it handles:
struct X {};
template<class C, typename T1, bool (C::*F)(T1)>
inline // there are more for T1..TN
bool wrap(C* c, X x)
{
return (c->*F)(process<T1>(x));
}
template<class C, typename T1, bool (C::*F)(T1)>
inline // there are more for T1..TN
boost::function<bool (C*, X)> make_fn(F f) // <- problem here, F is not a type
{
return boost::bind(&wrap<C, T1, F>, _1, _2);
}
With this however, vc++ and g++ don't see F as a type for the parameter of make_fn(). I must miss something obvious here and am feeling somewhat blind.
The idea was that it should work like this:
struct A
{
bool f1(bool) { return true; }
};
void test()
{
A a;
X x;
make_fn(&A::f1)(&a, x);
}
Any ideas on how to make that work?
Background:
I have a fixed interface which, when simplified, looks like this:
bool invoke(C* c, const char* const functionName, int argCount, X* args);
X is a variant type which i have to convert to certain backend types (int, std::string, ...).
To handle these calls i have a map of functors that are looked up by name and map these calls to member functions of some instance.
The intention of the wrapping is to avoid manual conversions and instead generate functors which do the conversion for me or throw. I have this working with a macro based solution, but that solution requires to specify the types and the parameter count explicitly.
Via function overload resolution i hope to generate the correct converting functor implicitly from the member function signature.
It appears to me that you are attempting to turn a pointer passed to a function into a non-type template argument, which I'm afraid is not going to work (see comments to your question).
What you could do, is to store the function pointer in a function object. The following appears to compile:
#include <boost/bind.hpp>
#include <boost/function.hpp>
struct X {};
template <class T>
bool process(X) { return true; }
template <class C, class T1, class Func>
struct wrap1
{
typedef bool result_type;
Func f;
wrap1(Func f): f(f) {}
bool operator()(C* c, X x)
{
return (c->*f)(process<T1>(x));
}
};
template<class C, typename T1>
inline // there are more for T1..TN
boost::function<bool (C*, X)> make_fn(bool (C::*f)(T1))
{
return boost::bind(wrap1<C, T1, bool (C::*)(T1)>(f), _1, _2);
}
struct A
{
bool f1(bool) { return true; }
};
void test()
{
A a;
X x;
make_fn(&A::f1)(&a, x);
}
However, I'm not sure if that is any good and how you would create the rest of the wrappers. For the latter you might just get a compiler that supports variadic templates. :)