MrRoy
MrRoy

Reputation: 1183

Calling multiple functions with similar names

If I have multiple functions that have a similar name (ie fct1, fct2, fct3...), and I'm calling them from a menu that takes the function number in parameter, is there a way to call them without making a switch with every function?

I'm thinking of something similar to this: fct[c](); //c is entered by the user, which of course doesn't work.

Upvotes: 2

Views: 224

Answers (4)

JoeFish
JoeFish

Reputation: 3100

You could pre-declare a list of function pointers. Thusly:

void Func1() { std::cout << "Func1" << std::endl; }
void Func2() { std::cout << "Func2" << std::endl; }
void Func3() { std::cout << "Func3" << std::endl; }

void (*funcList[])() = {Func1, Func2, Func3};

int main()
{
    funcList[0]();
    funcList[1]();
    funcList[2]();  
} 
Func1
Func2
Func3
Press any key to continue . . .

Edit: an example of initializing the array at runtime - it's like any other array of values, it just looks funny when declared.

void (*funcList[3])() = {};

void InitFuncList()
{
    funcList[0] = Func1;
    funcList[1] = Func2;
    funcList[2] = Func3;
}

Upvotes: 1

Andr&#233; Caron
Andr&#233; Caron

Reputation: 45239

If the functions all have the same signature, you can put function pointers into an array. For instance,

int option1 ()
{
}

int option2 ()
{
}

typedef int(*option)();

const option options[] = {
    &option1,
    &option2,
};
int n = sizeof(options) / sizeof(option);

int main ( int, char ** )
{
    for ( int choice = 0; (std::cin >> choice); )
    {
        if ((choice < 0) || (choice >= n)) {
            std::cout << "Invalid option." << std::endl;
        } else {
            (*options[choice])();
        }
    }
}

Upvotes: 0

parapura rajkumar
parapura rajkumar

Reputation: 24403

Insert them all to map... key is the std::string which is the function name value is a function pointer.

Once you initialize the map you can use map look up to find and execute the function and avoid a switch statement

typedef void (*Foo)(void);

std::map< std::string , Foo> FunctionMap;
//Change key type to int if numbers are needed

void PrintA()
{
    std::cout << "PrintA" << std::endl;
}

void PrintB()
{
    std::cout << "PrintA" << std::endl;
}

void ExecuteFunction( const std::string& funcName )
{
    std::map< std::string , Foo>::const_iterator iter = FunctionMap.find(funcName);
    if ( iter != FunctionMap.end() )
    {
        Foo f = iter->second;
        f();
    }
}

int main()
{

    FunctionMap["PrintA"] = PrintA;
    FunctionMap["PrintB"] = PrintB;

    ExecuteFunction("PrintA");

    return 0;
}

Upvotes: 5

Steve Jessop
Steve Jessop

Reputation: 279195

Your only option in standard C++ is to populate some kind of lookup from keys to function pointers. That could be a map using the strings as keys, or an array using the number as an index, or for that matter the switch you mentioned or a big old if/else statement comparing string values.

If you're willing to write non-portable code, look at the facilities that your system provides for looking up functions by name in an executable (dlsym, GetProcAddress or equivalent). As long as your functions are available in a symbol table, you can get at them that way. The question becomes almost equivalent to Is it possible to call a C function, given its name as a string?, except that you also have C++ name mangling to worry about.

Upvotes: 0

Related Questions