Как вызвать функцию по имени (std :: string) в C ++?

Интересно, есть ли простой способ вызвать функцию из строки. Я знаю простой способ, используя «if» и «else».

int function_1(int i, int j) { return i*j; } int function_2(int i, int j) { return i/j; } ... ... ... int function_N(int i, int j) { return i+j; } int main(int argc, char* argv[]) { int i = 4, j = 2; string function = "function_2"; cout << callFunction(i, j, function) << endl; return 0; } 

Это основной подход

 int callFunction(int i, int j, string function) { if(function == "function_1") { return function_1(i, j); } else if(function == "function_2") { return function_2(i, j); } else if(...) { } ... ... ... ... return function_1(i, j); } 

Есть что-то более простое?

 /* New Approach */ int callFunction(int i, int j, string function) { /* I need something simple */ return function(i, j); } 

То, что вы описали, называется reflectionм, а C ++ его не поддерживает. Однако вы можете столкнуться с некоторыми проблемами, например, в этом конкретном случае вы можете использовать std::map , который сопоставляет имена функций ( std::string objects) с указателями функций, которые в случае функций с такой же прототип может быть проще, чем может показаться:

 #include  #include  int add(int i, int j) { return i+j; } int sub(int i, int j) { return ij; } typedef int (*FnPtr)(int, int); int main() { // initialization: std::map myMap; myMap["add"] = add; myMap["sub"] = sub; // usage: std::string s("add"); int res = myMap[s](2,3); std::cout << res; } 

Обратите внимание, что myMap[s](2,3) извлекает указатель функции, отображаемый в строку s и вызывает эту функцию, передавая ей 2 и 3 , делая вывод этого примера равным 5

Использование карты стандартной строки для стандартных функций.

 #include  #include  #include  #include  int add(int x, int y) {return x+y;} int sub(int x, int y) {return xy;} int main() { std::map> funcMap = {{ "add", add}, { "sub", sub} }; std::cout << funcMap["add"](2,3) << "\n"; std::cout << funcMap["sub"](5,2) << "\n"; } 

Еще лучше с Лямбдой:

 #include  #include  #include  #include  int main() { std::map> funcMap = {{ "add", [](int x, int y){return x+y;}}, { "sub", [](int x, int y){return xy;}} }; std::cout << funcMap["add"](2,3) << "\n"; std::cout << funcMap["sub"](5,2) << "\n"; } 

Существует еще одна возможность, которая еще не упоминалась, что является истинным reflectionм.

Опцией для этого является доступ к функциям, экспортированным из исполняемого файла или совместно используемой библиотеки, с использованием функций операционной системы для разрешения имен на адреса. Это интересное использование, например, загрузка двух библиотек ‘contant’ в программу ‘umpire’, так что люди могут выталкивать ее из-за того, что их фактические коды сражаются друг с другом (играя Reversi или Quake, что бы то ни было).

Другой вариант – доступ к информации отладки, созданной компилятором. В Windows это может быть удивительно легко для компиляторов, которые совместимы, поскольку вся работа может быть отключена для системных DLL или бесплатных DLL, загружаемых из Microsoft. Часть функциональности уже содержится в Windows API.

Однако это больше относится к категории системного программирования – независимо от языка – и, следовательно, оно относится к C ++ только постольку, поскольку это язык системного программирования par excellence.

  • Могу ли я «размножить» строку (в C #)?
  • Использование локалей с Java toLowerCase () и toUpperCase ()
  • Как получить количество символов в std :: string?
  • Использование значений Enum как строковых литералов
  • Использование DocumentFilter.FilterBypass
  • Проверить строку для палиндрома
  • Легальность реализации COW std :: string в C ++ 11
  • Разница между «char» и «String» в Java
  • Получить имя файла из строки URI в C #
  • Pandas: найдите столбец, имя которого содержит определенную строку
  • Как разбирать строку в nullable int
  • Interesting Posts

    Android Gradle plugin 0.7.0: «дубликаты файлов при упаковке APK»

    Воспроизведение аудио через сеть с помощью Windows 7?

    UIScrollview с UIButtons – как воссоздать трамплин?

    android CountDownTimer – дополнительная задержка в миллисекундах между тиками

    Что произойдет, если я отклоняю / разрешаю несколько раз в цикле Крисковаля?

    Обновление подсистемы Linux в Windows (Ubuntu) до 16.04

    Сделать любое оконное приложение «Always On Top» без сочетания клавиш?

    Возможно ли преобразовать SSL-сертификат из файла .key в .pfx?

    Как изменить fragmentы с помощью Android-навигатора

    В чем разница между префиксными и постфиксными операторами?

    ERR_ICANN_NAME_COLLISION при попытке использовать localhost .dev в Chrome

    Как использовать Buffered Reader в Java

    Запустить программу как admin без ввода учетных данных? (Автоматическая высота Win7)

    Измените размер изображения в соответствии с JLabel

    Как настроить страницу приветствия на действие struts?

    Давайте будем гением компьютера.