使用 std::function 作为参数的可变参数模板
Variadic templates using std::function as parameter
如何简化下面的代码。是否可以在这里使用元组?如果是,你能解释一下如何。
template<typename Out, typename T1, typename T2, typename T3, typename T4>
void ProcessIncomingCommand(PClientContext pClientContext,
DWORD & bytesProcessed,
const std::function<Out(T1, T2, T3, T4)> &function,
const std::vector<UINT> ¶ms);
template<typename Out, typename T1, typename T2, typename T3>
static void ProcessIncomingCommand(PClientContext pClientContext,
DWORD & bytesProcessed,
const std::function<Out(T1, T2, T3)> &function,
const std::vector<UINT> ¶ms);
template<typename Out, typename T1, typename T2>
static void ProcessIncomingCommand(PClientContext pClientContext,
DWORD & bytesProcessed,
const std::function<Out(T1, T2)> &function,
const std::vector<UINT> ¶ms);
在模板实现中需要调用函数,参数由UINT
的std::vector
传递。参数可能不同,因此需要将它们强制转换为正确的类型。
auto resFromFunction= function(params.at(0),
params.at(1),
static_cast<T3>(params.at(2)),
static_cast<T4>(params.at(3)));
我如何在这里使用 log0 答案?
template<typename Out, typename... T>static void ProcessIncomingCommand(PClientContext pClientContext,
DWORD & bytesProcessed,
const std::function<Out(T...)> &function,
const std::vector<UINT> ¶ms)
不确定...但我想你需要一个函数助手和std::index_sequence
(或类似的东西(。
一个可能的例子
template <typename Out, typename ... Ts, std::size_t ... Is>
static Out PIC_helper (
PClientContext pClientContext,
DWORD & bytesProcessed,
const std::function<Out(Ts...)> &function,
const std::vector<UINT> ¶ms,
std::index_sequence<Is...> const &)
{ return function( static_cast<Ts>(params.at(Is))... ); }
template <typename Out, typename ... Ts>
static void ProcessIncomingCommand (
PClientContext pClientContext,
DWORD & bytesProcessed,
const std::function<Out(Ts...)> &function,
const std::vector<UINT> ¶ms)
{
Out resFromFunction
= PIC_helper(pClientContext, bytesProcessed, function, params,
std::make_index_sequence<sizeof...(Ts)>());
// other ...
}
观察std::index_sequence
和std::make_index_sequence()
是C++14特征;但是如果您需要C++11解决方案,则可以轻松创建一些东西来替代它们。
这将编译。
template<typename Out, typename... T>
static void ProcessIncomingCommand(PClientContext pClientContext,
DWORD & bytesProcessed,
const std::function<Out(T...)> &function,
const T&... params) { function(params...); }
int main()
{
PClientContext p;
DWORD d = 0.5;
std::function<int(double, int, char)> f;
double a;
int b;
char c;
ProcessIncomingCommand(p, d, f, a, b, c);
}
如果你想将参数作为元组传递,它会更棘手:请参阅如何将元组扩展为可变参数模板函数的参数?当然,如果您将function
更改为采用元组而不是参数列表......
看起来你想要类似的东西
template<typename ResultType, std::size_t... I>
ResultType tuple_from_vector_impl(std::vector<UINT> params, std::index_sequence<I...>)
{
return std::make_tuple(static_cast<decltype(std::get<I>(std::declval<ResultType>()))>(params[I])...);
}
template<typename... Args, typename Indices = std::index_sequence_for<Args...>>
std::tuple<Args...> tuple_from_vector(std::vector<UINT> params)
{
return tuple_from_vector_impl<std::tuple<Args...>>(params, Indices{});
}
template<typename Out, typename ... Args>
void ProcessIncomingCommand(PClientContext pClientContext,
DWORD & bytesProcessed,
const std::function<Out(Args...)> &function,
const std::vector<UINT> ¶ms)
{
// preamble
std::tuple<Args...> args = tuple_from_vector<Args...>(params);
Out result = std::apply(function, args);
// postamble
}
template<typename ... Args>
void ProcessIncomingCommand(PClientContext pClientContext,
DWORD & bytesProcessed,
const std::function<void(Args...)> &function,
const std::vector<UINT> ¶ms)
{
// preamble
std::tuple<Args...> args = tuple_from_vector<Args...>(params);
std::apply(function, args);
// postamble
}
相关文章:
- 在不传递参数数量且只有3个点的情况下,如何使用变差函数
- 如何使用可变参数模板强制转换每个变体类型
- 关于如何在具有单个参数的变体构造中选择替代方案?
- 调用参数排列不变函数 f(i++, i++)
- 参数归纳与标准::变体
- 模板化回调参数的逆变,如 C# 中的逆变
- 如何在没有参数包的情况下编写变差函数
- 通过具有嵌套类的工厂类获取多个变异类模板参数包
- 获取模板参数的成员变量值列表
- 保留短 lambda 用作函数的中间参数,使用 clang 格式保持不变
- 如何定义变体<x,y,z>提取模板参数的子类型
- 正确对齐内存模板,参数顺序不变
- 递归中不同参数类型的变元模板函数
- 通过函数指针传递给变差函数的参数会更改其值
- 提升预定义为带有参数的全局 lambda 的变体访问者
- 使用可变参数模板参数提升变体访问者
- boost ::变体 - 为什么模板参数比const字符串参数具有更高的优先级
- 将变参数包中的值加载到临时数组中
- 使用额外参数提升变体访客
- 正在将动态数组元素解析为参数?(变音符)