将函数参数类型提取为参数包
Extracting function argument types as a parameter pack
这是"解包"元组以调用匹配函数指针的后续问题,该指针询问如何以通用方式将std::tuple
中的值作为参数提供给函数。 给出的解决方案如下:
template<int ...>
struct seq { };
template<int N, int ...S>
struct gens : gens<N-1, N-1, S...> { };
template<int ...S>
struct gens<0, S...>
{
typedef seq<S...> type;
};
double foo(int x, float y, double z)
{
return x + y + z;
}
template <typename... Args>
struct save_it_for_later
{
std::tuple<Args...> params;
double (*func)(Args...);
double delayed_dispatch()
{
return callFunc(typename gens<sizeof...(Args)>::type());
}
template<int ...S>
double callFunc(seq<S...>)
{
return func(std::get<S>(params) ...);
}
};
int main(void)
{
std::tuple<int, float, double> t = std::make_tuple(1, 1.2, 5);
save_it_for_later<int,float, double> saved = {t, foo};
std::cout << saved.delayed_dispatch() << std::endl;
}
我的问题是是否有办法制作仅将foo
作为模板参数的save_it_for_later
的替代版本,这样我们就不必提供foo
的参数类型作为模板参数(或将其返回类型烘焙到save_it_for_later
)。 类似的东西
int main(void) {
...
save_it_for_later2<foo> saved = {t};
...
}
我同样可以使用某种宏包装foo
来提取所需的类型:
int main(void) {
...
save_it_for_later<MACRO_USING_DECLTYPE_OR_SOMESUCH(foo)> saved = {t};
...
}
这种担忧似乎与原始问题正交,足以保证自己的票证。
#include <tuple>
#include <utility>
template <typename> struct save_it_for_later_t;
template <typename Result, typename... Args>
struct save_it_for_later_t<Result (*)(Args...)> {
std::tuple<Args...> params;
Result (*fun)(Args...);
template <typename... Params>
save_it_for_later_t(Result (*fun)(Args...), Params&&... params)
: params(std::forward<Params>(params)...)
, fun(fun) {
}
// ...
};
template <typename Result, typename... Args, typename... Params>
save_it_for_later_t<Result(*)(Args...)>
save_it_for_later(Result (*fun)(Args...), Params&&... params) {
return save_it_for_later_t<Result(*)(Args...)>(fun, std::forward<Params>(params)...);
}
double foo(float, float, double);
int main() {
auto saved = save_it_for_later(foo, 1.2f, 3.4f, 5.6);
// ...
}
我只是羞怯地发现我去年问过一个类似的问题(将函数参数的参数解压缩到C++模板类),这也在这里得到了答案:
#include <functional>
#include <iostream>
#include <tuple>
template<int ...>
struct seq { };
template<int N, int ...S>
struct gens : gens<N-1, N-1, S...> { };
template<int ...S>
struct gens<0, S...>
{
typedef seq<S...> type;
};
double foo(int x, float y, double z)
{
return x + y + z;
}
template<typename T>
struct save_it_for_later;
template <typename Result, typename... Args>
struct save_it_for_later<Result(Args...)>
{
std::tuple<Args...> params;
Result (*func)(Args...);
Result delayed_dispatch()
{
return callFunc(typename gens<sizeof...(Args)>::type());
}
template<int ...S>
Result callFunc(seq<S...>)
{
return func(std::get<S>(params) ...);
}
};
int main(void)
{
std::tuple<int, float, double> t = std::make_tuple(1, 1.2, 5);
save_it_for_later<decltype(foo)> saved = {t, foo};
std::cout << saved.delayed_dispatch() << std::endl;
}
相关文章:
- 将不同类型的模板参数包提取到双精度向量中会产生警告
- 如何提取模板参数中传递的类型
- C/C++预处理器:提取每秒的可变参数
- C++ 模板提取布尔参数
- 从模板参数的模板参数中提取值
- 使用C++元编程提取 C 函数的参数("Practical C++ Metaprogramming" 中的示例)
- 如何定义变体<x,y,z>提取模板参数的子类型
- 使用命令行参数从TXT文件中提取并在C 中运行特定类
- 为什么我只从可变参数模板中提取一个值?
- 提取模板参数的值
- C++从函数签名中提取参数
- 每个新客户端的 GStreamer 和 URI 查询参数提取
- 从文件名中提取文件名,路径来自参数
- 从参数包中提取成员类型
- 是否保证标准提取运算符>>在失败时不会更改参数?
- 从boost ::函数中提取参数
- 从结构中提取指针参数
- 如何实现递归"using"/提取模板参数
- 制作解析器以提取函数名称、参数、返回类型
- 从net.connman.Manager的GetService方法动态提取D-Bus参数和对象路径