作为模板参数的函数
functions as template arguments
我有一个TaskWrapper:
template <typename T, T (*F)(T)>
struct TaskWrapper {
static inline T run(T clock) {
return F(clock);
}
};
要使用它,我必须指定T模板参数:
uint16_t task1(uint16_t clock) { return clock + 1; }
typedef tasks::TaskWrapper<uint16_t, task1> Task;
我想简单地写:
typedef tasks::TaskWrapper<task1> Task;
,让编译器计算出返回值和参数类型是uint16_t。
指出:
TaskWrapper显然被简化了,实际上还有一些其他的参数,这些参数是在类型定义期间传递的。
包装函数只能是:
uint8_t task(uint8_t clock);
uint16_t task(uint16_t clock); // or
uint32_t task(uint32_t clock);
TaskWrapper作为模板参数传递给另一个类,该类将在某个时候调用Task::run(…);
c++ 11就可以了
仅从c++ 17的模板
template <auto F>
struct TaskWrapper {
template <typename T>
static inline auto run(T clock) {
return F(clock);
}
};
uint16_t task1(uint16_t clock) { return clock + 1; }
typedef TaskWrapper<&task1> Task; // ok
您可以将模板参数移动到调用的位置,但这会使它与传递给演绎的参数相对应,例如:
template <typename F, F functor>
struct TaskWrapper {
template<typename T>
static inline T run(T clock) {
return functor(clock);
}
};
uint16_t task1(uint16_t clock) { return clock + 1; }
typedef TaskWrapper<decltype(task1), task1> Task;
int main(int argc, const char * argv[])
{
Task task;
Task::run(10);
return 0;
}
这样它将生成一个static inline int run(int clock)
,它与初始函数的参数类型不同,但对于您的目的来说已经足够了。
使用类型而不是值作为参数时,模板很容易。你能把函数转换成函子吗?如果是,那么可能的解决方案如下:
template<class F>
struct TaskWrapper {
using T = decltype(F::operator());
static inline T run(T clock) {
return F(clock);
}
};
struct task1_t {
uint16_t operator()(uint16_t clock) {
return clock + 1;
}
};
using Task = TaskWrapper<task1_t>;
我不认为这是可能的,你到底问什么:如果你想传递函数作为模板值,不表达类型,你必须知道类型之前;但是函数的类型是你想要推断的。
如果接受传递函数的类型,如下所示
template <typename>
struct taskWrapper;
template <typename T>
struct taskWrapper<std::function<T(T)>>
{
static inline T run (std::function<T(T)> const & F, T clock)
{ return F(clock); };
};
你可以定义定义你的typedef
s
typedef taskWrapper<std::function<decltype(task8)>> tsk8;
typedef taskWrapper<std::function<decltype(task16)>> tsk16;
typedef taskWrapper<std::function<decltype(task32)>> tsk32;
,但可以看到taskWrapper<std::function<decltype(task8)>>
只知道task8()
的类型,不知道task8()
函数本身;所以你必须把函数传递给run()
。
下面是一个工作示例:
#include <iostream>
#include <functional>
template <typename>
struct taskWrapper;
template <typename T>
struct taskWrapper<std::function<T(T)>>
{
static inline T run (std::function<T(T)> const & F, T clock)
{ return F(clock); };
};
uint8_t task8 (uint8_t clock)
{ return ++clock; }
uint16_t task16 (uint16_t clock)
{ return ++clock; }
uint32_t task32 (uint32_t clock)
{ return ++clock; }
typedef taskWrapper<std::function<decltype(task8)>> tsk8;
typedef taskWrapper<std::function<decltype(task16)>> tsk16;
typedef taskWrapper<std::function<decltype(task32)>> tsk32;
int main ()
{
tsk8 t8;
tsk16 t16;
tsk32 t32;
std::cout << t8.run(task8, uint8_t(64)) << std::endl; // print A
std::cout << t16.run(task16, uint16_t(65)) << std::endl; // print 66
std::cout << t32.run(task32, uint32_t(66)) << std::endl; // print 67
}
相关文章:
- static_assert在宏中,但也可以扩展到可以用作函数参数的东西
- C++中的高效循环缓冲区,它将被传递给C样式数组函数参数
- 当从函数参数中的临时值调用复制构造函数时
- 如何从"decltype()"获取函数参数的数量<funtion>?
- 如何将lambda作为模板类的成员函数参数
- 模板参数推导失败,函数参数/参数不匹配
- 如何在C++中将迭代器作为函数参数传递
- 将函数参数"const char*"转换为"std::string_view"是
- C++ 如何将数组值解压缩为函数参数
- 主函数参数的属性
- 具有两个间接寻址运算符 (C++) 的函数参数的用途
- "Warning: Comma within array index expression"但逗号分隔函数参数
- 如何定义在用作函数参数时工作的类模板的转换
- 将函数参数完美转发到函数指针:按值传递呢?
- 为什么我不能将引用作为 std::async 的函数参数传递
- 什么..(省略号)作为函数原型中唯一的函数参数,C++?
- 是否可以就地构造一个固定大小的数组作为函数参数?
- 接受模板作为函数参数
- 将成员函数作为构造函数参数调用时出错 "Variable is not a type name"
- Arduino 函数参数