枚举可变模板参数包
Enumerate variadic template parameter pack
我有 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...>());
}
我有 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...>());
}