兼容带const引用或拷贝参数函数的函数指针适配问题
解决apply_op适配op1和op2的问题
你遇到的核心问题是函数签名不匹配:op1接受的是const My_container<T>&类型的参数,而op2接受的是My_container<T>值类型的参数,但你原来的apply_op只接受以值为参数的函数指针,所以op1根本传不进去。
下面给你两种优雅的解决方案,其中第一种是最通用的:
方案一:用模板参数接受任意可调用对象
直接把apply_op改成一个接受任意可调用类型的模板函数,这样不管是op1、op2,还是lambda、自定义 functor,都能完美适配:
template <class T, typename Op> void apply_op(const My_container<T> &a, Op op) { op(a); }
为什么这个方案可行?
当你传入op1时,op(a)会自动匹配op1的const My_container<T>&参数,直接传递引用,完全符合op1的需求;当你传入op2时,编译器会自动把a拷贝一份,作为值传递给op2,正好满足op2的参数要求。
举个调用的例子:
My_container<int> my_vec; // 调用op1,传递const引用 apply_op(my_vec, op1<int>); // 调用op2,自动拷贝my_vec传递过去 apply_op(my_vec, op2<int>);
方案二:重载apply_op适配不同的函数指针
如果你只想针对函数指针做适配,也可以写两个重载版本,分别对应两种函数签名:
// 适配op1:接受const引用参数的函数指针 template <class T> void apply_op(const My_container<T> &a, void (*op)(const My_container<T>&)) { op(a); } // 适配op2:接受值参数的函数指针 template <class T> void apply_op(const My_container<T> &a, void (*op)(My_container<T>)) { op(a); // 这里会自动拷贝a传递给op2 }
这种方案只针对函数指针有效,灵活性不如第一种,但如果你的场景只需要支持这两个函数,也能解决问题。
总结
优先选方案一,它的通用性最强,不仅能解决当前的问题,还能应对未来可能出现的其他可调用类型,代码也更简洁。
内容的提问来源于stack exchange,提问作者Todor Markov
相关产品推荐
相关产品推荐

