我想知道是否可以使用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;
}
就我而言,这种设置和保持函数指针手动映射的方法非常不雅致。有没有一种“自动”方式?
答案 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;
}