Вызов функции по строковому названию
Как вызвать функцию по строковому имени?
Пример использования:
void foo() {}
void bar() {}
int main() {
call("foo"); // вызывает первую функцию
call("bar"); // вызывает вторую функцию
}
Как написать такой call?
Достаточно решения для самых простых случаев - нешаблонных ничего не возвращающих функций без перегрузок.
Ответы (2 шт):
Автор решения: Harry
→ Ссылка
void foo() { cout << "foo\n"; }
void bar() { cout << "bar\n"; }
typedef void (*funcptr)();
pair<const char*,funcptr> fs[] = { {"bar",bar}, {"foo",foo}};
void call(const char * fname)
{
for(int i = 0; i < sizeof(fs)/sizeof(*fs); ++i)
if (strcmp(fs[i].first,fname)== 0)
{
fs[i].second();
break;
}
}
int main() {
call("foo"); // вызывает первую функцию
call("bar"); // вызывает вторую функцию
}
Например, так. Вопрос только - зачем?!
Автор решения: Ildar
→ Ссылка
можно так, для функций с одинаковыми сигнатурами
#include <iostream>
#include <map>
#include <string>
#include <functional>
namespace Caller
{
std::map<std::string, std::function<void()>> functions;
void call(const std::string& functionName);
}
void Caller::call(const std::string& functionName)
{
functions[functionName]();
}
void foo()
{
std::cout << "foo\n";
}
void bar()
{
std::cout << "bar\n";
}
int main()
{
Caller::functions["foo"] = foo;
Caller::functions["bar"] = bar;
Caller::call("foo");
Caller::call("bar");
return 0;
}
UPDATE:
если вызываем call с функцией которой нет в словаре, то создаться новый элемент автоматически и вызовется function по умолчанию, который бросит исключение, поэтому нужно или перехватить исключение или же обработать этот момент например как @Harry c поиском функции заранее
вариант с ловлей исключения:
void Caller::call(const std::string& functionName)
{
try {
functions[functionName]();
}
catch (const std::exception& e) {
std::cout << e.what() << '\n';
}
}