按名称解析 C++ 方法

C++ method resolution by name

我想知道是否有一种方法可以在 C++ 中编写一个函数,该函数将仅根据方法名称解析对象方法(具体示例如下)。 运行 时间或编译时间分辨率(例如模板)都可以接受。我已经阅读了一些关于模板元编程的内容,但我希望在深入研究之前我能得到一些信息,了解这是否是解决我的问题的合适方向。

本质上,我正在尝试编写一个函数来调用传入对象的非静态方法,例如这个伪代码:

exampleFunction(Object myObject, ObjectMethod myObjectMethod) {
    // do some stuff here

    myObject.myObjectMethod(arguments);

    // do some more stuff here
}

在这种情况下,我无法将方法硬编码到 exampleFunction 中,而只是让我调用它的每个对象都具有该方法名称。我必须能够灵活地使用各种方法调用 exampleFunction,并正确解析这些方法中的每一个。此外,我必须能够解析 methods,并且这些方法必须是 non-static。就我而言,我必须能够在方法调用时修改内部私有对象成员。不深入细节,这些约束是我正在处理的系统的产物,我无法更改。

正如我之前所说,编译时间和 运行 时间解决方案都是可以接受的。所以像这样的模板在我的情况下也能很好地工作:

template <ObjectMethodName methodName>
exampleFunction(Object myObject) {
    // do some stuff here

    myObject.methodName(arguments);

    // do some more stuff here
}

任何关于这是否可能的想法,以及关于可能实施的信息,我们将不胜感激。

可以将 pointer-to-member-function 作为模板参数传递。

这是一种示例方法。

#include <iostream>

struct Foo {
    void print() {
        std::cout << "Foo\n";
    }

    void printVal(int val) {
        std::cout << "val = " << val << "\n";
    }
};

template <auto F, typename T, typename... Args>
void exampleFunc(T& obj, Args&&... args) {
    (obj.*F)(args...);
}

int main()
{
    Foo foo;
    exampleFunc<&Foo::print>(foo);
    exampleFunc<&Foo::printVal>(foo, 5);
}

使用auto模板参数需要c++17。

您可以使exampleFunction成为一个函数模板,它具有对象类型的第一个参数,第二个参数可以是对成员指针的引用函数,第三个参数是函数参数包,表示调用成员函数时要传递的参数。

#include <iostream>

class Actions {
  public:
    Actions(){}
    void doSmthg(){
        std::cout<<"do something called"<<std::endl;
    }
    void multipleArgs(int, int)
    {
        std::cout<<"multiple int args called"<<std::endl;
    }
};
class Entity
{
    public:
    void func(double)
    {
        std::cout<<"func called"<<std::endl;
    }
};
template<typename T, typename Callable, typename... Args>
void exampleFunction(T obj, const Callable& callable, const Args&... args){
    std::cout<<"exampleFunction called"<<std::endl;
    //call the function on the passed object
    (obj.*callable)(args...);
}


int main()
{
    Actions action;
    
    exampleFunction(action, &Actions::doSmthg); //calls doSmthg member function with 0 arguments 
    exampleFunction(action, &Actions::multipleArgs, 5,7);//calls multipleArgs member function with 2 int arguments
    
    Entity e;
    exampleFunction(e, &Entity::func,4.4); //calls func member function 
}

Demo

以上程序的输出为:

exampleFunction called
do something called
exampleFunction called
multiple int args called
exampleFunction called
func called