#include <iostream>
#include <functional>
#include <type_traits>
// TODO: provide your definition of what this actually is
// (sounds like you already have one)
struct NATIVEVALUE {};
// from your question
typedef int (*EXTENSIONFUNCTION)(NATIVEVALUE args[]);
// TODO: provide overloads for conversion of supported data
// types to the NATIVEVALUE construction.
NATIVEVALUE nv_conv(int value)
{
std::cout << __PRETTY_FUNCTION__ << '\n';
NATIVEVALUE nv = {};
return nv;
}
NATIVEVALUE nv_conv(double dbl)
{
std::cout << __PRETTY_FUNCTION__ << '\n';
NATIVEVALUE nv = {};
return nv;
}
NATIVEVALUE nv_conv(unsigned int ui)
{
std::cout << __PRETTY_FUNCTION__ << '\n';
NATIVEVALUE nv = {};
return nv;
}
NATIVEVALUE nv_conv(char c)
{
std::cout << __PRETTY_FUNCTION__ << '\n';
NATIVEVALUE nv = {};
return nv;
}
// object wrapper for holding the callback and provide call-operator
// overloads (template and empty)
struct Callable
{
EXTENSIONFUNCTION m_pfn;
Callable(EXTENSIONFUNCTION pfn) : m_pfn(pfn) {}
template<class Arg, class... Args>
int operator()(Arg arg, Args... args)
{
std::cout << __PRETTY_FUNCTION__ << '\n';
NATIVEVALUE nv_args[] = { nv_conv(arg), nv_conv(args)... };
return m_pfn(nv_args);
}
// no arg overload
int operator()()
{
std::cout << __PRETTY_FUNCTION__ << '\n';
return m_pfn(NULL);
}
};
int nv_callback(NATIVEVALUE args[])
{
std::cout << __PRETTY_FUNCTION__ << '\n';
return 0;
}
int main()
{
auto fn = std::bind(Callable(nv_callback), 1, 2.0, 03, 4U, '5');
fn();
auto fn2 = std::bind(Callable(nv_callback));
fn2();
return 0;
}