将lambda传递给接受模板化类型函数的函数
pass lambda to function that accepts function with templated types
我正在尝试创建一个模板函数,它将一个函数作为形参,并且形参函数具有供模板推断的参数。
的例子:
这是一个接受固定函数类型并工作的函数
void func_a(void(*func)(int)) {
func(1);
}
int main() {
auto f = [](int x) -> void { printf("%in", x); };
func_a(f);
return 0;
}
这是我想做的,扩展第一个例子(这将无法编译)
template <typename... T>
void func_b(void(*func)(T...)) {
func(1);
}
int main() {
auto f = [](int x) -> void { printf("%in", x); };
func_b(f); // neither of
func_b<int>(f); // these work
return 0;
}
理想情况下,我希望func_b
接受常规函数和lambda函数,如func_a
所做的,但与模板魔术。
不幸的是,模板演绎不能很好地处理隐式转换。但是,可以显式地将lambda转换为函数指针类型。最短但有些令人困惑的方法是应用一元+操作符:
func_b(+f);
或者您可以使用更直观的,但也冗长且违反dry的强制转换操作:
func_b(static_cast<void(*)(int)>(f));
但是,也许你只想接受任何可调用类型,而不仅仅是函数指针:
template <class Fun>
void func_c(Fun&& func) {
func(1);
}
这在lambdas中工作得很好。不涉及转换
func_c(f);
并且它也适用于捕获lambda(不能转换为函数指针),std::function
和函数对象,例如在<functional>
中定义的那些。
这里有一些可用的选项:
#include <functional>
template <typename T>
void func_b(T&& func) {
func(1);
}
template <typename... T>
void func_c(std::function<void(T...)> func) {
func(1);
}
template <typename... T>
void func_d1(std::function<void(T...)> func) {
func(1);
}
template<typename... Params>
using fun = std::function<void(Params...)>;
template <typename T, typename... P>
void func_d(T& func) {
func_d1(fun<P...>(func));
}
int main() {
auto f = [](int x) { printf("%in", x); };
func_b(f);
func_b(std::function<void(int)>(f));
func_c(std::function<void(int)>(f));
func_d<decltype(f),int>(f);
return 0;
}
问题是:lambda是不是一个函数指针或std::function
-object。
func_b
使用完全转发,因此T
将是lambda的类型,而不是std::function
对象。
For func_c
。不应该将lambda转换为c风格的函数指针。std::function
对象能够进行这种转换,但只能显式地(通过设计)进行转换,因此您需要显式地转换它们。
func_d
(和func_d1
)结合了其他方面。它转发lambda并显式地从中生成std::function
-object,尽管它需要一个额外的模板参数。
相关文章:
- 为什么在我的函数类型后使用引用运算符 (&) 允许我修改它返回的值?
- 来自 DLL 的函数调用 [表观调用的括号前面的表达式必须具有(指向-)函数类型]
- 是否有任何建议来统一函数类型限定符并简化可恶的函数类型?
- 关于 C++ 中的函数类型定义
- 用于检测函数类型是否为否的特征
- 函数类型参数的模板参数推导
- 标准对此指向成员函数类型模板参数有何说明?是我的代码有误,还是 MSVS 16.6 有问题?
- C++无效的函数类型转换
- STL 函数和函数类型与函数指针类型
- 如何将result_of与函数类型定义一起使用
- 将模板(没有规范)传递给 std::thread() 会出现错误:<未解析的重载函数类型>匹配错误
- C++ 编译错误:gnu_printf是无法识别的格式函数类型
- 专门用于"direct"函数类型(与函数指针类型相对)
- 将函数类型作为模板参数传递不会编译
- 通过参数传递 lambda(无函数类型模板)
- 如何在模板参数中分离函数类型返回类型和参数
- 为什么比较函数类型需要指定为模板参数?
- 带有限定符的函数类型定义用例
- 如何声明对函数类型的常量引用
- 非类型模板参数允许各种函数类型?