如何在C ++中重新分配函数名称

Jon*_*Jon 3 c++ c++17

我在C ++中有一个与此示例问题类似的问题。在这种情况下,我有两个具有相同接口的成员函数。根据传递给超级函数的字符串中的信息,我想将两个成员函数之一分配给变量class_func。有没有办法做到这一点?

// test.hpp
class TestClass
{
public:
    double master_function(double a, double b, std::string func_name);
private:
    double add(double a, double b);
    double subtract(double a, double b);
};

// test.cpp
double TestClass::master_function(double a, double b, std::string func_name)
{
    if (func_name == std::string("Add") const auto& class_func = add;
    else const auto& class_func = subtract;
    return class_func(a, b);
}
// =========================================================================

double TestClass::add(double a, double b)
{
    return a + b;
}
// =========================================================================

double TestClass::subtract(double a, double b)
{
    return a - b;
}
Run Code Online (Sandbox Code Playgroud)

换句话说,我正在尝试将成员函数addsubtract名称分配给class_func,因此无论用户要使用哪个函数,if语句中的代码master_function都可以统一。在下面显示的表格中,我得到了错误Reference to non-static member function must be called out,但是我不确定这意味着什么或如何解决。另外,我正在使用C ++ 17编译器,因此,如果有一种最适合C ++ 17的现代方法,我会对学习它感兴趣。

Log*_*uff 6

您要查找的术语是成员函数指针,但是我们可以在不显式指定该类型的情况下进行操作。代码的问题不仅在于尝试引用成员函数的方式(可能是&TestClass::add),还在于您在嵌套范围内(在if/ 下else)创建这些别名,这意味着它们在return声明。

最简单的更改是这样的:

auto class_func = &TestClass::add; // pick one default

if (func_name == "Subtract")
{
    class_func = &TestClass::subtract;
}
else
{
    assert(func_name == "Add"); // optional
}

return class_func(a, b);
Run Code Online (Sandbox Code Playgroud)

之所以起作用是因为addsubtract函数具有完全相同的类型:

double (TestClass::*)(double a, double b)
Run Code Online (Sandbox Code Playgroud)

但是,是的,为什么没有这些功能static?它们不适用于类的实例。使它们static和上面的内容仍然有效,只需注意的类型class_fun将是一个简单的函数指针:

double (*)(double a, double b)
Run Code Online (Sandbox Code Playgroud)

现在您已经知道类型了,您可以以一种不会在代码中的一个函数先于另一个函数的方式来对其进行更改:

decltype(&TestClass::add) class_func = nullptr;

if (func_name == "Add")
{
    class_func = &TestClass::add;
}
else if (func_name == "Subtract")
{
    class_func = &TestClass::subtract;
}

assert(class_func != nullptr);
return class_func(a, b);
Run Code Online (Sandbox Code Playgroud)

如注释中所述,随着if- else链开始变长,在字符串和函数指针之间使用(hash)映射变得越来越有意义。