使用C ++ RTTI(自省)按字符串查找函数指针?

时间:2019-05-02 12:44:00

标签: c++ rtti

我想知道是否可以使用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 个答案:

答案 0 :(得分:5)

您愿意使用library(tidyverse) group_stat <- function(df, group_var, summary_var, .f) { func <- rlang::as_closure(.f) group_var <- rlang::enquo(group_var) summary_var <-rlang::enquo(summary_var) name <- paste0(rlang::quo_name(summary_var), "_", deparse(substitute(.f))) df %>% dplyr::group_by(!!group_var) %>% dplyr::summarise(!!name := func(!!summary_var, na.rm = TRUE)) } mtcars %>% group_stat(group_var = cyl, summary_var = disp, median) #> # A tibble: 3 x 2 #> cyl disp_median #> <dbl> <dbl> #> 1 4 108 #> 2 6 168. #> 3 8 350. mtcars %>% group_stat(group_var = cyl, summary_var = disp, mean) #> # A tibble: 3 x 2 #> cyl disp_mean #> <dbl> <dbl> #> 1 4 105. #> 2 6 183. #> 3 8 353. mtcars %>% group_stat(group_var = cyl, summary_var = disp, max) #> # A tibble: 3 x 2 #> cyl disp_max #> <dbl> <dbl> #> 1 4 147. #> 2 6 258 #> 3 8 472 mtcars %>% group_stat(group_var = cyl, summary_var = disp, min) #> # A tibble: 3 x 2 #> cyl disp_min #> <dbl> <dbl> #> 1 4 71.1 #> 2 6 145 #> 3 8 276. 吗?如果是这样,您可以通过解析__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;
}

在线示例:https://rextester.com/OHZK79342