HI!
The compilation under Linux (Fedora 23) with GCC run, but with VS2013 or 2015 I got a complier error.
ambiguous ....
Please try it and maybe someone knwos a solution!
First of all the code of the templates itself:
/* ############################################ */
#pragma one
#include <vector>
#include <iostream>
#include <functional>
#include <stdexcept>
#include <string>
#include <boost/any.hpp>
template <typename Ret, typename Func>
class InCppFunction
{
public:
InCppFunction(Func func, std::string name, size_t paraNum) :
m_function(func), m_name(name), m_paraNum(paraNum)
{
};
~InCppFunction()
{
};
boost::any Call(std::vector<boost::any> param)
{
if (param.size() != m_paraNum)
{
throw std::runtime_error("InCppFunction::Call: wrong number of parameters");
}
m_adapt = Adaptfunc(m_function);
return boost::any_cast<Ret>(m_adapt(param));
};
protected:
template <typename... Args>
Ret CallFunc(std::function<Ret(Args...)> func, std::vector<boost::any> anyargs);
Ret CallFunc (std::function<Ret()> func, std::vector<boost::any> anyargs)
{
if (anyargs.size() > 0)
{
throw std::runtime_error("oops, argument list too long");
}
return func();
};
template <typename Arg0, typename... Args>
Ret CallFunc (std::function<Ret(Arg0, Args...)> func, std::vector<boost::any> anyargs)
{
if (anyargs.size() == 0)
{
throw std::runtime_error("oops, argument list too short");
}
Arg0 arg0 = boost::any_cast<Arg0>(anyargs[0]);
anyargs.erase(anyargs.begin());
std::function<Ret(Args... args)> lambda = ([=](Args... args) -> Ret
{
return func(arg0, args...);
});
return CallFunc(lambda, anyargs);
}
template <typename... Args>
std::function<boost::any(std::vector<boost::any>)> Adaptfunc(Ret (*func)(Args...))
{
std::function<Ret(Args...)> stdfunc = func;
std::function<boost::any(std::vector<boost::any>)> result = ([=](std::vector<boost::any> anyargs) -> boost::any
{
return boost::any(CallFunc(stdfunc, anyargs));
});
return result;
}
private:
Func m_function;
std::function<boost::any(std::vector<boost::any>)> m_adapt;
std::string m_name;
size_t m_paraNum;
};
/* ############################################ */
Now some test functions:
/* ############################################ */
#pragma one
#include <iostream>
int func1 (int a)
{
std::cout << "func1(" << a << ") = ";
return 33;
};
int func2 (double a, std::string b)
{
std::cout << "func2(" << a << ",\"" << b << "\") = ";
return 7;
};
int func3 (std::string a, double b)
{
std::cout << "func3(" << a << ",\"" << b << "\") = ";
return 7;
};
int func4 (int a, int b)
{
std::cout << "func4(" << a << "," << b << ") = ";
return a+b;
};
/* ############################################ */
And now main:
/* ############################################ */
#include "TemplateClass.h"
#include "TestFunctions.h"
int main (int argc, char *argv[])
{
auto funcTest1 = InCppFunction<int, int(*)(int)>(func1, "func1", 1);
auto funcTest2 = InCppFunction<int, int(*)(double, std::string)>(func2, "func2", 2);
auto funcTest3 = InCppFunction<int, int(*)(std::string, double)>(func3, "func3", 2);
auto funcTest4 = InCppFunction<int, int(*)(int, int)>(func4, "func4", 2);
std::cout << boost::any_cast<int>(funcTest1.Call({777})) << std::endl;
std::cout << boost::any_cast<int>(funcTest2.Call({66.6, std::string("yeah right")})) << std::endl;
std::cout << boost::any_cast<int>(funcTest3.Call({std::string("whatever"), 0.123})) << std::endl;
std::cout << boost::any_cast<int>(funcTest4.Call({3, 2})) << std::endl;
}
/* ############################################ */