C++重载成员函数指针运算符->*时const版本编译失败如何解决
修复C++
operator->* 重载适配const成员函数调用的方案 核心问题根源
- Functor类的无参调用运算符
operator()定义了额外的模板参数RETURN_TYPE,调用时没有显式指定的话编译器无法推导,直接调用()必然触发语法错误。 - const版本
operator->*的模板参数设计错误,多余的模板参数T无法被自动推导,导致该重载永远不会被匹配到,const成员函数指针会被传入非const版本的operator->*生成Functor实例。
修复方案
所有修改均未使用lambda、std::function,符合要求。
1. 修改Functor.h实现
移除无参调用运算符的冗余模板参数,通过decltype自动推导成员函数调用的返回值:
#pragma once #include "RecordCard.h" #include <utility> // 仅用于std::declval做类型推导,无其他依赖 template <class OBJECT_TYPE, typename POINTER_TO_MEMBER> class Functor{ public: Functor(OBJECT_TYPE* pObj, POINTER_TO_MEMBER pMF):m_pObj(pObj),m_pMF(pMF){} // 移除RETURN_TYPE模板参数,自动推导返回值 auto operator()() const -> decltype((std::declval<OBJECT_TYPE*>()->*std::declval<POINTER_TO_MEMBER>)()) { return (m_pObj->*m_pMF)(); } template <typename PARAM_TYPE> void operator()(PARAM_TYPE param) { (m_pObj->*m_pMF)(param); } private: OBJECT_TYPE* m_pObj; POINTER_TO_MEMBER m_pMF; };
2. 修改RecordCard.h的const版本operator->*定义
删除无法推导的冗余模板参数,修正后重载可被正常匹配:
// 非const版本保持原有实现不变 template <typename T> Functor<RecordCard,T> operator->*(T pmf) { return Functor<RecordCard,T>(this, pmf); } // 清理冗余模板参数,删除错误的默认参数定义 template <typename U> const Functor<RecordCard,U> operator->*(U pmf) const { return Functor<RecordCard,U>(this, pmf); }
验证效果
原有Main.cpp无需任何修改,(mycard->*&RecordCard::SetAge)(30)和(mycard->*&RecordCard::GetAge)()均可正常运行,const修饰的RecordCard对象调用成员函数时也会自动匹配const版本的operator->*。
内容的提问来源于stack exchange,提问作者SparkieMember
相关产品推荐
相关产品推荐

