Reputation: 1183
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
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
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
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
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