Вот вариант. Только с вас — как обязательное условие :) — демонстрация того, как именно вы будете это все использовать...
#include <iostream>
#include <map>
typedef void (*sFunc)(const std::string &);
typedef void (*iFunc)(const int &);
void printStr(const std::string & str)
{
std::cout << str << std::endl;
}
void printInt(const int & i)
{
std::cout << i << std::endl;
}
int main()
{
std::map<std::string, void*> map;
map["prints"] = (void*)printStr;
map["printi"] = (void*)printInt;
(sFunc(map["prints"]))("12345");
(iFunc(map["printi"]))(1234);
return 0;
}
Update
Набросал простенькое решение, как бы, возможно, делал я (хотя уже вижу ряд улучшений).
#include <vector>
#include <string>
#include <iostream>
#include <sstream>
using namespace std;
class Func
{
public:
virtual string name() const = 0;
virtual void doit(const string&) = 0;
};
vector<Func*> funcs;
class Sum: public Func
{
public:
string name() const override { return "sum"; }
void doit(const string& s)
{
istringstream is(s);
int a, b;
string n;
is >> n >> a >> b;
cout << a << " + " << b << " = " << (a+b) << endl;
}
};
class Str: public Func
{
public:
string name() const override { return "str"; }
void doit(const string& s)
{
cout << "string = " << s << endl;
}
};
void handle(const string& s)
{
for(const auto& f: funcs)
if (s.starts_with(f->name()))
{
f->doit(s);
break;
}
}
int main(int argc, char * argv[])
{
funcs.push_back(new Sum);
funcs.push_back(new Str);
handle("sum 5 8");
handle("str Hello world");
}
Есть абстрактный класс, производные — ваши функции, выполняющие сами разбор строки (им виднее!) и нужные вызовы. Объект вносится в какой-то контейнер, при разборе строки выбирается подходящий и работает. Ошибки не обрабатываю, чисто набросок, как и высосанная из пальца функциональность...
Все, что надо для расширения функциональности (новая функция) — новый класс, 2 функции, объект класса в контейнер. Все.