C++重载成员函数指针如何匹配CreateTestSuite模板的不同重载版本
方案1:无需修改现有实现,调用时显式转换成员函数指针类型
你可以在传参时用static_cast明确指定要取的重载版本的函数指针类型,编译器就能正确匹配:
// 选择非const版本 CreateTestSuite(static_cast<return_type(A::*)(...)>(&A::test)); // 选择const版本 CreateTestSuite(static_cast<return_type(A::*)(...) const>(&A::test));
这个方案的优势是完全不用改动现有CreateTestSuite的代码,适合不想调整模板实现的场景。
方案2:小幅修改模板,新增标签参数显式选择
如果觉得每次调用都写static_cast太麻烦,可以给两个重载新增无意义的标签参数用来区分:
首先定义两个空标签类型:
struct non_const_mem_fn {}; struct const_mem_fn {};
然后修改两个CreateTestSuite重载,分别加上标签参数(可以给默认值,不影响原有正常调用):
// 非const版本,带默认标签参数 template <typename C, typename RT, typename... P> auto CreateTestSuite(RT(C::* pFunc)(P...), non_const_mem_fn = {}) {...} // const版本 template <typename C, typename RT, typename... P> auto CreateTestSuite(RT(C::* pFunc)(P...) const, const_mem_fn = {}) {...}
之后遇到重载成员函数时,只要传入对应的标签就能指定匹配版本:
// 选择非const版本 CreateTestSuite(&A::test, non_const_mem_fn{}); // 选择const版本 CreateTestSuite(&A::test, const_mem_fn{});
原有不存在重载的成员函数指针传入时,不需要加标签,编译器会自动匹配,完全兼容之前的调用逻辑。
方案3(C++20及以上):给模板增加布尔模板参数显式指定
如果项目允许使用C++20,还可以通过约束区分两个模板重载,支持直接通过模板参数指定版本:
template <bool IsConst = false, typename C, typename RT, typename... P> requires (!IsConst) auto CreateTestSuite(RT(C::* pFunc)(P...)) {...} template <bool IsConst = false, typename C, typename RT, typename... P> requires (IsConst) auto CreateTestSuite(RT(C::* pFunc)(P...) const) {...}
调用时显式指定模板参数即可:
// 选择非const版本 CreateTestSuite<false>(&A::test); // 选择const版本 CreateTestSuite<true>(&A::test);
内容的提问来源于stack exchange,提问作者Guanyuming He
相关产品推荐
相关产品推荐

