Reputation: 9527
In C++, is possible to make something like this:
class A
{
public:
template <typename ClassType, typename MethodName, typename ...Args>
static func()
{
ClassType t = GetPtr<ClassType>();
t->MethodName(GetArg<Args>()...);
}
}
A::func<B, sum, double, double>(); //should call B->sum(double, double)
A::func<C, sum2, std::string, double, double>(); //should call C->sum2(std::string, double, double)
where GetPtr
and GetArgs
are working methods to obtain pointers from dictionary.
Upvotes: 3
Views: 748
Reputation: 13988
You could make use of non-type template parameters like:
template <typename ClassType, typename MethodType, MethodType MethodName, typename ...Args>
static void func() {
ClassType t = GetPtr<ClassType>();
(t->*MethodName)(GetArg<Args>()...);
}
to use it as follows:
A::func<B, double (B::*)(double,double), &B::sum, double, double>();
When your compiler will support c++17 your code could get even shortened:
template <typename ClassType, auto MethodName, typename ...Args>
static void func() {
ClassType t = GetPtr<ClassType>();
(t->*MethodName)(GetArg<Args>()...);
}
With usage:
A::func<B, &B::sum, double, double>();
Upvotes: 4
Reputation: 36337
as the word typename
suggests, no, this won't work (generally), but:
you can basically just create a class that overloads operator(.)
, and do the calling inside the overloaded operator.
In fact, Boost::bind
does exactly that and allows you to get "functor" objects that you can pass around at runtime as objects.
Upvotes: 1
Reputation: 66200
Not exactly what you asked, but I suppose you can do someting like
#include <array>
#include <vector>
#include <iostream>
template <typename Class, typename Method, typename ... Args>
void callMethod (Class & c, Method m, Args ... args)
{ ((&c)->*m)(args...); }
int main()
{
std::vector<int> v;
std::array<int, 5U> a;
callMethod(v, &std::vector<int>::size);
callMethod(v, static_cast<void (std::vector<int>::*)(int const &)>
(&std::vector<int>::push_back), 7);
callMethod(a, &std::array<int, 5U>::fill, 3);
std::cout << v.back() << std::endl; // print "7"
for ( auto const i : a )
std::cout << i << std::endl; // print "3" five times
}
Observe that with push_back()
method of std::vector<int>
, you need a cast (static_cast<void (std::vector<int>::*)(int const &)>
) to resolve the overloading ambiguity (there are two push_back()
in std::vector<int>
)
Not sure about the use of GetPtr()
and GetArgs()
, but I suppose you can use callMethod()
as follows
callMethod(GetPtr<B>(), &B::sum, GetArgs<double>(),
GetArgs<double>());
callMethod(GetPtr<C>(), &C::sum2, GetArgs<std::string>(),
GetArgs<double>(), GetArgs<double>());
Upvotes: 1