如何为模板(成员)函数使用函数模板签名?C++11是否支持?
问题描述
我想要创建一个可生成仿函数对象的(成员)函数,希望以函数签名形式提供所需模板参数,示例代码:
auto f = create<int(double)>();
我了解针对std::function这类对象的实现方式:
template <class, class> struct Functor; template <class Ret, class... Args> struct Functor<Ret(Args...)> { };
请问如何为模板(成员)函数实现相同的行为?该功能能否在C++11中实现?
实现方案
完全可以实现,且该功能支持C++11标准,核心思路是利用模板偏特化提取函数签名里的返回值和参数类型,再将逻辑封装到模板函数(或成员函数)中。
1. 非成员模板函数实现
先通过辅助模板结构体提取函数签名的信息,再让create模板函数调用该结构体的逻辑生成仿函数:
#include <iostream> #include <tuple> // 辅助模板,用于提取函数签名的返回值和参数 template <class Sig> struct FunctorTraits; template <class Ret, class... Args> struct FunctorTraits<Ret(Args...)> { using ReturnType = Ret; // 自定义仿函数实现,可根据需求修改逻辑 struct Impl { ReturnType operator()(Args... args) const { // 示例:返回第一个参数的2倍 return static_cast<ReturnType>(2 * std::get<0>(std::make_tuple(args...))); } }; }; // 模板函数,接收函数签名作为模板参数,生成对应仿函数对象 template <class Sig> typename FunctorTraits<Sig>::Impl create() { return typename FunctorTraits<Sig>::Impl(); } int main() { auto f = create<int(double)>(); std::cout << f(3.14) << std::endl; // 输出6 return 0; }
2. 成员模板函数实现
如果要把create作为类的成员函数,只需将模板函数封装到类内部,逻辑与非成员版本一致:
#include <iostream> #include <tuple> template <class Sig> struct FunctorTraits; template <class Ret, class... Args> struct FunctorTraits<Ret(Args...)> { using ReturnType = Ret; struct Impl { ReturnType operator()(Args... args) const { return static_cast<ReturnType>(2 * std::get<0>(std::make_tuple(args...))); } }; }; class FunctorGenerator { public: template <class Sig> typename FunctorTraits<Sig>::Impl create() const { return typename FunctorTraits<Sig>::Impl(); } }; int main() { FunctorGenerator gen; auto f = gen.create<int(double)>(); std::cout << f(3.14) << std::endl; // 输出6 return 0; }
C++11兼容性说明
- 代码中用到的可变参数模板(
Args...)、std::tuple、std::get以及auto变量推导都是C++11标准引入的特性,完全兼容。 - 若需要更复杂的仿函数逻辑,直接修改
FunctorTraits::Impl中的operator()实现即可。
内容的提问来源于stack exchange,提问作者Mehno
相关产品推荐
相关产品推荐

