我在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;
}
换句话说,我正在尝试将成员函数add
或subtract
分配给名称class_func
,因此{{ 1}}可以统一,无论用户要使用哪种功能。在下面显示的表单中,我收到错误if
,但是我不确定这意味着什么或如何解决。另外,我使用的是C ++ 17编译器,因此,如果有一种最适合C ++ 17的现代方法,我会对学习它感兴趣。
答案 0 :(得分:6)
您要查找的术语是成员函数指针,但是我们可以在不显式指定该类型的情况下进行操作。代码的问题不仅在于您尝试引用成员函数的方式(即&TestClass::add
),还在于您在嵌套范围(在if
/ {下)中创建了这些别名。 {1}}),这意味着它们不会在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);
和add
函数具有完全相同的类型:
subtract
但是,是的,为什么这些功能不是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);
-if
链开始变长,因此在字符串和函数指针之间使用(散列)映射变得越来越有意义。