如何获取已完成模板参数推导的模板函数指针?
获取自动推导模板参数的函数指针用于std::bind
首先得修正你原代码里的小问题:func函数声明为void但却返回了rst,这会编译报错,我们先把它改成返回TContainer<TR>类型:
#include <vector> #include <functional> #include <utility> // 假设HeadOf是取参数包第一个类型的工具,示例实现如下 template<typename T, typename... Rest> struct HeadOf { using type = T; }; class A{}; class B{}; class C{}; template<template<typename...> class TContainer, typename TR, typename... TEles> TContainer<TR> func(TContainer<TEles...> container, std::function<TR(typename HeadOf<TEles...>::type)> f) { TContainer<TR> rst; for(auto it : container) { rst.push_back(f(it)); // 假设fill是将结果加入容器,这里用push_back做示例 } return rst; } // 自定义容器示例(补充必要的基础实现) template<typename T, typename Alloc, typename Sth> class MyContainer { public: void push_back(const T&) {} // 支持范围for循环的基础实现 auto begin() const { return nullptr; } auto end() const { return nullptr; } };
接下来解决核心问题:怎么拿到自动推导后的func函数指针。
直接写&func编译器会报错,因为模板参数TContainer、TR、TEles...都没有明确指定,编译器不知道要实例化哪个版本。我们可以用一个辅助函数帮我们自动推导这些参数,无需手动写模板参数:
// 辅助函数:根据容器和function对象推导模板参数,返回对应函数指针 template<template<typename...> class TContainer, typename TR, typename... TEles> auto func_ptr_of(TContainer<TEles...>, std::function<TR(typename HeadOf<TEles...>::type)>) -> decltype(&func<TContainer, TR, TEles...>) { return &func<TContainer, TR, TEles...>; } // 重载版本:处理普通函数、lambda等可转换为std::function的调用对象 template<template<typename...> class TContainer, typename F, typename... TEles> auto func_ptr_of(TContainer<TEles...> container, F f) -> decltype(func_ptr_of(container, std::function(f))) { return func_ptr_of(container, std::function(f)); }
现在你就可以像预期的那样使用了:
// 定义转换函数(用lambda示例) std::function<B(A)> transA2B = [](const A&) { return B(); }; std::function<C(B)> transB2C = [](const B&) { return C(); }; std::vector<A> vec_A; MyContainer<B, std::allocator<B>, int> cont_B; // 自定义容器实例 // 获取函数指针 auto ptrFoo = func_ptr_of(vec_A, transA2B); auto ptrBar = func_ptr_of(cont_B, transB2C); // 用std::bind绑定参数 auto contB2contC = std::bind(ptrBar, std::placeholders::_1, transB2C); // 调用绑定后的函数 contB2contC(cont_B);
为什么不能直接用func_ptr_of(func(vec_A, transA2B))?
因为func(vec_A, transA2B)会实际执行函数,返回的是TContainer<TR>类型的容器对象,而不是函数指针。我们的辅助函数func_ptr_of是通过传入容器和函数对象的类型来推导模板参数,不会执行func本身。
内容的提问来源于stack exchange,提问作者WangChu
相关产品推荐
相关产品推荐

