首页 > 解决方案 > 如何在 C++ 中重新分配函数名

问题描述

我在 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;
}

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

标签: c++c++17

解决方案


您正在寻找的术语是成员函数指针,但我们可以不明确指定该类型。您的代码的问题不仅在于您尝试引用成员函数(即&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);

这是有效的,因为addandsubtract函数具有完全相同的类型:

double (TestClass::*)(double a, double b)

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

double (*)(double a, double b)

既然您知道了类型,您就可以在代码中以一种不在另一个函数之前特权的方式进行更改:

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

正如评论中提到的,随着ifelse开始变长,在字符串和函数指针之间使用(散列)映射变得越来越有意义。


推荐阅读