c++ - 枚举可变参数模板参数包
问题描述
我有std::vector<val_t>
(val_t
- 我自己的实现std::any
),它包含我要调用的函数的参数和一个Args
包含该函数的参数类型的参数包。
using arg_pack_t = std::vector<val_t>;
template <typename R, typename... Args>
class function_reflector_t<R (*)(Args...)> {
typedef R (*c_function_t)(Args...);
using reflected_t = signature_reflector_t<R, Args...>;
public:
static function_metadata_t reflect(std::string name, c_function_t c_function)
{
// HERE!
universal_wrapper_t invoke = [](arg_pack_t args) -> val_t {
return args[0].as<c_functon_t>()(args[??? + 1].as<Args>()...);
};
return {
reinterpret_cast<void *>(c_function),
nullptr,
invoke,
std::move(name),
reflected_t::arguments(),
reflected_t::return_type(),
};
}
};
要调用此函数,我需要将参数类型与相同参数的索引相关联,因此在完成所有模板实例化之后,编译器可以生成与以下内容等效的代码:
universal_wrapper_t invoke = [](arg_pack_t args) -> val_t {
return args[0].as<c_functon_t>()(args[1].as<int>(), args[2].as<double>());
};
我读到过,std::integer_sequence
但在这种情况下我想不出一种使用它的方法。理想情况下,我需要一些这样的模板std::index_sequence_for
,而不是size_t
提供一个类型,该类型在该索引处具有索引和类型的别名,所以它的行为有点像 python 的enumerate
.
解决方案
你可能会这样做:
template <std::size_t ... Is>
static function_metadata_t reflect(std::string name,
c_function_t c_function,
std::index_sequence<Is...>)
{
universal_wrapper_t invoke = [](arg_pack_t args) -> val_t {
return args[0].as<c_functon_t>()(args[Is + 1].as<Args>()...);
};
return {
reinterpret_cast<void *>(c_function),
nullptr,
invoke,
std::move(name),
reflected_t::arguments(),
reflected_t::return_type(),
};
}
static function_metadata_t reflect(std::string name, c_function_t c_function)
{
return reflect(name, c_function, std::index_sequence_for<Args...>());
}
推荐阅读
- php - 无法将我的登录页面重定向到主页
- android - 底部的 ScrollView 和 SwitchPreferences 会导致行为不稳定。为什么每当我切换 SwitchePreference 时列表会向上滚动?
- angularjs - 通过复选框检查多选问题的答案以显示正确答案
- git - 覆盖所有未提交的本地文件
- android - 如何解决 Android Studio 中的渲染问题?
- python - 使用单行从字符串python中过滤掉数字
- wordpress - 保持所有 WordPress 环境同步
- node.js - Electron --serve 因缺少 package.json 而失败
- javascript - 如何在 VScode 中显示导入的函数签名/jsdoc?
- java - Maven:“NoClassDefFoundError:com/jogamp/newt/event/KeyListener”