How do I re-assign a function name in C++

自闭症网瘾萝莉.ら 提交于 2019-12-10 21:52:01

问题


I have a problem in C++ that is similar to this example problem. In this case I have two member-functions that have an identical interface. Based on the information in a string passed to the super function, I would like to assign one of the two member functions to the variable class_func. Is there a way to do this?

// 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;
}

In other words, I am trying to assign the member-function add or subtract to the name class_func, so the code underneath the if statement in master_function can be uniform regardless of which function the user wants to use. In the form shown below I get the error Reference to non-static member function must be called out, but I am not totally sure what this means or how to fix it. In addition, I am using a C++17 compiler, so if there is a modern approach that works best with C++17 I would be interested in learning it.


回答1:


The term you are looking for is member function pointer, but we can do without explicitly specifying that type. The problem with your code is not only in the way you try to refer to a member function (that would be &TestClass::add), but also that you create those aliases in a nested scope (under if/else), meaning they won't be visible in the return statement.

The simplest change is this:

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

This works because the add and subtract functions have the exact same type:

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

But yeah, why are those functions not static? They do not work with a class' instance. Make them static and the above will still work, just note that the type of class_fun will be a simple function pointer:

double (*)(double a, double b)

Now that you know the types, you could change this in a way that does not privilege one function before the other in the code:

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

As mentioned in the comments, as that if-else chain starts to get longer, it makes more and more sense to use a (hash)map between strings and function pointers.



来源:https://stackoverflow.com/questions/56212392/how-do-i-re-assign-a-function-name-in-c

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