如何修复用于求值嵌套成员指针的C++可变参数模板编译错误
修复嵌套成员指针求值的C++可变参数模板
你的代码主要有两个核心问题导致编译失败:
- 递归调用时错误地对可变参数取地址(
&args...),但这些参数本身已经是成员指针类型 - 递归模板未返回递归调用的结果,同时
decltype的推导逻辑也存在偏差
下面是修复后的代码,完全兼容不支持auto模板参数的编译器:
#include <iostream> using namespace std; // 递归终止模板:处理最后一层成员指针 template<typename T, typename U> U getField(T& input, U (T::*field)) { return input.*field; } // 可变参数递归模板:逐层拆解嵌套成员 template<typename T, typename U, typename V, typename... Rest> auto getField(T& input, U (T::*firstField), V (U::*nextField), Rest... args) -> decltype(getField(input.*firstField, nextField, args...)) { return getField(input.*firstField, nextField, args...); } struct inner { int val; }; struct outer { inner in; }; int main() { // 注意:C++标准要求main返回类型必须是int,不能是void outer p{{5}}; cout << getField(p, &outer::in, &inner::val) << endl; return 0; }
关键修改点说明:
修正参数传递逻辑:
原代码中getField(input.*field, &args...)错误地给成员指针参数取地址,现在改为直接传递nextField和args...——因为这些参数本身就是对应类型的成员指针(比如&inner::val是int (inner::*)类型)。明确递归模板的参数类型:
把可变参数模板的第二个参数明确为V (U::*nextField),让编译器能清晰推导每一层成员指针的所属类型,避免模板参数推导模糊的问题。修复返回值问题:
递归模板添加了return语句,同时通过decltype(getField(...))递归推导返回类型,确保每一层的返回类型都能正确匹配。修正main函数合规性:
C++标准强制要求main函数返回类型为int,原代码的void main()不符合标准,会引发编译警告或错误。
编译运行这段代码后,就能正确输出5,也就是p.in.val的值。
内容的提问来源于stack exchange,提问作者Jeff G
相关产品推荐
相关产品推荐

