C++模板中U T::*含义及成员函数指针类型推导规则
核心概念澄清:
U T::*的语法含义 U T::*是C++中指向类非静态成员的指针类型匹配模式,其中:
T是成员所属的类类型U是被指向的成员本身的完整类型- 该模式可以匹配两类成员指针:指向非静态成员变量的指针、指向非静态成员函数的指针
推导错误的根源:成员函数指针的语法优先级问题
你之前认为&A::fun的类型是int A::*() const&,这个写法本身不符合C语法规则,核心是运算符优先级的问题:
C中函数调用运算符()的优先级高于成员指针运算符*,如果不加括号限定,int A::*() const&会被解析为「返回值类型为int A::*(指向类A的int成员的指针)的普通函数类型」,根本不是成员函数指针。
指向A::fun的成员函数指针的正确写法是:
int (A::*)() const&
这里的括号强制把A::*和指针符号绑定,明确这是一个指向类A成员的指针。
该场景下的完整类型推导过程
- 首先确定
decltype(&A::fun)的真实类型:就是上述的int (A::*)() const&,含义是「指向类A的成员函数的指针,该成员函数无参数、带const&限定、返回值为int」。 - 将该类型与偏特化模板的模式
U T::*做模式匹配:- 模式中
T::*对应的是成员指针中「归属类+指针属性」的部分,也就是上述类型里的(A::*)段,因此直接推导出模板参数T = A。 - 类型中剩下的、成员指针所指向的目标本身的类型,就会被推导为
U。去掉(A::*)段后,剩余的类型段是int () const&——这就是成员函数fun本身的类型(带const&引用限定、无参数、返回int的函数类型)。
- 模式中
- 因此
PM_traits<decltype(&A::fun)>::member_type最终就是int () const&,这也是为什么std::is_function_v<T>会返回true:int() const&本身就是一个合法的函数类型。
对比验证(符合初始推导预期的场景)
如果类A中存在一个普通int成员变量:
struct A { int x; };
此时&A::x的类型是int A::*,和U T::*模式匹配时,T推导为A,U推导为int,此时member_type就是int,和你最初的推导预期一致——这是因为普通成员变量的类型本身就是int,没有额外的函数签名、限定符部分。
内容的提问来源于stack exchange,提问作者irasin
相关产品推荐
相关产品推荐

