如何在C++11类模板中不使用auto传递函数?
C++11环境下传递函数到类模板的可行方案
错误原因分析
你之前的代码报错,是因为decltype(comp)得到的是函数类型bool(Arm, Arm),而在Myfunc中直接写F(v[l], v[r]),相当于试图用函数类型作为可调用对象,这在C++中是不允许的——函数类型本身不能直接调用,必须使用函数指针、仿函数或其他可调用实体。
下面是三种C++11环境下的可行解决方案:
方案一:使用函数指针作为模板参数
修改类模板,将第二个模板参数明确指定为函数指针类型,实例化时传递函数地址:
// 调整后的类模板 template<typename T, bool (*F)(T, T)> class Myclass { public: T v[10]; // 改用模板参数T,保持通用性 bool Myfunc(int i) { int l = i, r = i + 1; return F(v[l], v[r]); // 直接通过函数指针调用 } }; // 实例化对象 Myclass<Arm, &comp> obj;
方案二:使用仿函数(Functor)替代普通函数
把比较逻辑封装成重载operator()的结构体,将该结构体类型作为模板参数传递:
// 定义仿函数 struct Comp { bool operator()(Arm l, Arm r) { return l.len < r.len; } }; // 原类模板无需修改 template<typename T, typename F> class Myclass { public: T v[10]; bool Myfunc(int i) { int l = i, r = i + 1; return F()(v[l], v[r]); // 构造仿函数实例并调用operator() // 或者在类中添加F func;成员,调用func(v[l], v[r])避免临时对象构造 } }; // 实例化对象 Myclass<Arm, Comp> obj;
方案三:使用std::function包装函数
将std::function作为模板参数类型,实例化时传递函数对象,支持多种可调用实体:
#include <functional> // 原类模板调整为存储可调用对象 template<typename T, typename F> class Myclass { public: T v[10]; F func; // 构造函数初始化可调用对象 Myclass(F f) : func(f) {} bool Myfunc(int i) { int l = i, r = i + 1; return func(v[l], v[r]); } }; // 实例化对象 Myclass<Arm, std::function<bool(Arm, Arm)>> obj(comp);
内容的提问来源于stack exchange,提问作者A. J. Sinha
相关产品推荐
相关产品推荐

