C++模板特化能否将类私有成员变量、函数作为参数?
结论
MSVC的行为不符合C标准,所提供的代码是合法的C代码,GCC与Clang的编译结果符合标准要求。
相关规则说明
- C++的访问权限检查作用于成员名字被实际使用的上下文,而非声明上下文。
- 针对模板显式特化的非类型模板参数,访问权限不会在特化声明阶段检查,仅会在该特化被实际实例化、使用的位置触发检查。
代码逻辑验证
代码中两处S的显式特化均声明在全局作用域,该阶段仅完成特化声明,不存在对私有成员的实际使用,无需触发访问权限校验。
两处特化的实际使用位置都在C::f成员函数内部,C::f作为C类的成员函数,本身拥有C类所有私有成员的访问权限,因此在该上下文使用&C::x和&C::f作为模板参数完全符合标准要求。
MSVC的问题
本次报错是MSVC的已知编译器bug,存在两处不符合标准的表现:
- 错误地在模板显式特化的声明阶段执行访问权限检查,而非在特化的实际使用阶段检查。
- 对成员变量指针、成员函数指针的处理逻辑不一致:对
&C::x的处理符合标准,对&C::f的处理逻辑存在缺陷,最终出现仅对成员函数指针报错的异常情况。
内容的提问来源于stack exchange,提问作者user541686
相关产品推荐
相关产品推荐

