如何确定作为模板参数传递的函数的首个参数类型?
从编译期函数模板参数中提取第一个参数类型
要实现从模板参数Func中直接提取其第一个参数的类型,无需额外添加模板参数,可以通过模板特化结合函数类型萃取来完成,具体步骤如下:
1. 定义参数类型萃取模板
先实现一个辅助模板,用于从函数类型中提取第一个参数的类型:
// 基础模板声明 template<typename Func> struct first_arg_type; // 特化:匹配普通函数指针 template<typename Ret, typename Arg, typename... Rest> struct first_arg_type<Ret(*)(Arg, Rest...)> { using type = Arg; }; // 特化:匹配成员函数指针(可选,根据需求添加) template<typename Ret, typename Class, typename Arg, typename... Rest> struct first_arg_type<Ret(Class::*)(Arg, Rest...)> { using type = Arg; }; // 特化:匹配无捕获lambda(C++20及以上支持) template<typename Class> struct first_arg_type<Class> { using type = typename first_arg_type<decltype(&Class::operator())>::type; }; // 别名模板,简化类型引用 template<typename Func> using first_arg_t = typename first_arg_type<Func>::type;
2. 改造run_func模板
利用上面的萃取模板,直接推导参数类型:
template<auto Func> void run_func(first_arg_t<decltype(Func)> value) { Func(value); }
3. 测试示例
// 普通测试函数 void func(int x) { // 业务逻辑 } // 无捕获lambda(C++20+) auto lambda_func = [](double d) { // 业务逻辑 }; int main() { // 绑定普通函数 auto function_runner = &run_func<&func>; function_runner(42); // 参数类型自动推导为int // 绑定无捕获lambda auto lambda_runner = &run_func<lambda_func>; lambda_runner(3.14); // 参数类型自动推导为double return 0; }
这样就满足了需求:Func是编译时常量,无需额外模板参数,直接从Func中提取第一个参数类型作为value的类型。
内容的提问来源于stack exchange,提问作者111111
相关产品推荐
相关产品推荐

