C++ template parameter as function call name

旧巷老猫 提交于 2019-12-12 16:04:58

问题


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.


回答1:


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>();



回答2:


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>());



回答3:


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.



来源:https://stackoverflow.com/questions/40072627/c-template-parameter-as-function-call-name

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!