Вызов функции по строковому названию

Как вызвать функцию по строковому имени?

Пример использования:

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';
  }
}
→ Ссылка