Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Return a function from a class

Tags:

c++

c++11

I want to be able to return a function from a class, so that I do not need to if-else through a return type.

I have a class that returns multiple strings. Instead, I want to return multiple functions.

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

What I want is: That the function handleMessage in the class Handler returns something so that in my main application I do not have to use if-else.

So the main looks like this:

function = handle.handleMessage(0); 

And the application will choose which function it will run. for example:

function = handle.handleMessage(0);  //will run func1 
function = handle.handleMessage(1);  //will run func2
like image 747
JeanClarity Avatar asked Apr 09 '19 08:04

JeanClarity


People also ask

Can a function return a class Python?

Everything in Python is an object. So, your functions can return numeric values ( int , float , and complex values), collections and sequences of objects ( list , tuple , dictionary , or set objects), user-defined objects, classes, functions, and even modules or packages.

How do you return a function?

A return statement ends the execution of a function, and returns control to the calling function. Execution resumes in the calling function at the point immediately following the call. A return statement can return a value to the calling function.

Can a class have a return?

The getReturnType() method of Method class Every Method has a return type whether it is void, int, double, string or any other datatype.

Can I return a function in Python?

Function returning another function in Python As we know functions are treated as first-class objects in Python, therefore we can return a function from another function. A first-class object is an object that can be assigned to a variable, passed as an argument to a function, or used as a return value in a function.


2 Answers

You can modify the member function such that it returns a function pointer, e.g.

using fptr = void (*)();

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

};

This can be invoked as follows

 Handler handle;
 auto f = handle.handleMessage(0);
 f();

Note that the above if-else if-else dispatch isn't ideal. Prefer a data member that stores the function pointers and associates them with a code, e.g. using a std::unordered_map.

Note that when you need to return stateful function objects in the future, this approach will fail. Then, you need to embrace std::function which is able to wrap lambdas with closures or custom types with an operator() overload.

like image 80
lubgr Avatar answered Oct 19 '22 23:10

lubgr


There are several ways to do so, the simplest one, you can use an std::function. In this example we returning a lambda function for each case. You can replace it with the functions you just wrote.

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 {
            ....
        }
    }
};

Then your main function becomes:

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

You can replace the swith/if case statement by an array storing the different functions, like they mentioned in the comments.

If you dont want to pay the extra virtual function call regarding the usage of an std::function, you can use an alias like the answer below or just the auto keyword:

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 {
            ....
        }
    }
};
like image 33
mohabouje Avatar answered Oct 20 '22 00:10

mohabouje