从一个类返回一个函数

Jea*_*ity 6 c++ c++11

我希望能够从类中返回一个函数,这样就不需要通过返回类型进行if-else操作。

我有一个返回多个字符串的类。相反,我想返回多个函数。

#include <iostream>

class Handler
{
private:

public:
    int handleMessage(int code)
    {
        return code+1;
    }

};

void func1();
void func2();
void func3();

int main (int argc, char *argv[])
{
    Handler handle;
    int code = handle.handleMessage(0);
    if(code == 1)
    {
        func1();
    }
    return 0;
}

void func1(){ std::cout << "1" << std::endl;}
void func2(){ std::cout << "2" << std::endl;}
void func3(){ std::cout << "3" << std::endl;}
Run Code Online (Sandbox Code Playgroud)

我想要的是:handleMessage类中的函数Handler返回某些内容,因此在我的主应用程序中,我不必使用if-else。

所以主要看起来像这样:

function = handle.handleMessage(0); 
Run Code Online (Sandbox Code Playgroud)

应用程序将选择它将运行的功能。例如:

function = handle.handleMessage(0);  //will run func1 
function = handle.handleMessage(1);  //will run func2
Run Code Online (Sandbox Code Playgroud)

moh*_*uje 6

有几种方法,最简单的一种是使用std::function。在此示例中,我们为每种情况返回一个lambda函数。您可以将其替换为刚编写的函数。

class Handler {
public:
    std::function<void()> handleMessage(int code) {
        code = code + 1; // ++code or whatever
        if (code == X) {
            return []() { std::cout << "Cool! I'am x!" << std::endl; };
        } else if (code == Y) {
            return []() { std::cout << "Cool! I'am x!" << std::endl; };
        } else if (...) {
            ...
        } else {
            ....
        }
    }
};
Run Code Online (Sandbox Code Playgroud)

然后您的主要功能变为:

int main (int argc, char *argv[]) {
    Handler handle;
    const auto func = handle.handleMessage(0);
    func();
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

您可以用存储不同函数的数组替换swith / if case语句,就像注释中提到的那样。

如果您不想支付有关的用法的额外虚拟函数调用,则std::function可以使用以下答案之类的别名或仅使用auto关键字:

class Handler {
public:
    constexpr auto handleMessage(int code) {
        code = code + 1; // ++code or whatever
        if (code == X) {
            return &func1;
        } else if (code == Y) {
            return &func2;
        } else if (...) {
            ...
        } else {
            ....
        }
    }
};
Run Code Online (Sandbox Code Playgroud)

  • 注意,“ std :: function”要付出额外的虚拟调用的代价。 (5认同)

lub*_*bgr 6

您可以修改成员函数,使其返回函数指针,例如

using fptr = void (*)();

struct Handler
{
    fptr handleMessage (int code)
    {
       if (code == 0)
          return &func1;
       else if (code == 1)
          return &func2;
       else
          return &func3;
    }

};
Run Code Online (Sandbox Code Playgroud)

可以如下调用

 Handler handle;
 auto f = handle.handleMessage(0);
 f();
Run Code Online (Sandbox Code Playgroud)

注意上面的if- else if- else调度不理想。最好是一个存储函数指针并将其与a关联的数据成员code,例如使用a std::unordered_map

请注意,当您将来需要返回有状态功能对象时,此方法将失败。然后,您需要拥抱std::function能够用闭包或自定义类型包装有operator()重载的lambda 。