Используете C ++ RTTI (самоанализ) для поиска указателей на функцию по строке? - PullRequest
2 голосов
/ 02 мая 2019

Интересно, возможно ли использовать RTTI, чтобы получить статический указатель на метод / функцию, используя его имя (переданное в виде строки)

Пока у меня есть следующий код:

#include <map>

int Foo() {
  return 42;
}

int Bar() {
  return 117;
}

typedef int (*function_ptr)();

int main() {
  std::map<std::string, function_ptr> fctmap;
  fctmap["Foo"] = Foo;
  fctmap["Bar"] = Bar;
}

Этот метод установки и сохранения ручного отображения указателей на функции, насколько мне известно, крайне неэлегатный. Есть ли «автоматический» способ?

1 Ответ

5 голосов
/ 02 мая 2019

Вы были бы открыты для использования __PRETTY_FUNCTION__? Если это так, вы можете получить имя функции, проанализировав строку __PRETTY_FUNCTION__.

Затем у вас может быть вспомогательная функция, которая вставляет указатели функций на карту.

#include <iostream>
#include <map>
#include <string>

using Map = std::map<std::string, int(*)()>;

//-------------------------------------//

template<int(*)()>
struct Get
{
    static constexpr std::string name()
    {
        std::string tmp = __PRETTY_FUNCTION__;
        auto s = tmp.find("= ");
        auto e = tmp.find("; ");
        return std::string(tmp.substr(s+2, e-s-2));
    }
};

template<int(*func)()>
void insert2map(Map &fctmap_)
{
    fctmap_[Get<func>::name()] = func;
}

//-------------------------------------//

int Foo()
{
    return 42;
}

int Bar()
{
    return 117;
}

int VeryVeryLongName()
{
    return 101;
}

//-------------------------------------//

int main()
{
    Map fctmap;

    insert2map<Foo>(fctmap);
    insert2map<Bar>(fctmap);
    insert2map<VeryVeryLongName>(fctmap);

    for (auto &&i : fctmap)
        std::cout<< i.first <<" -> "<<i.second() <<std::endl;
}

В этом случае, похоже, хорошо работает. Результаты:

Bar -> 117
Foo -> 42
VeryVeryLongName -> 101

Онлайн пример: https://rextester.com/OHZK79342

...