如何正确创建并使用指向结构体数组成员的指针方法?
结构体数组成员的通用Setter实现问题
我有一个包含多个unsigned short类型成员的结构体,需要给这些成员做范围校验的setter。之前针对单个成员用指向成员的指针实现了通用setter,运行正常:
#include <iostream> struct myStructure { unsigned short d1;// 取值范围 0~10 unsigned short d2; bool Set (unsigned short myStructure::*ptr, unsigned short data) { if (data <= 10) { this->*ptr = data; return true; } else { return false; } } } st {}; int main () { st.Set (&myStructure::d1, 2); // 修改值并返回true st.Set (&myStructure::d2, 20);// 20超出范围,返回false std::cout << st.d1 << ',' << st.d2 ; // 输出 "2,0" return 0; }
现在要给结构体里的数组成员实现相同逻辑,我写了下面的方法:
struct myStructure { static const int N_ELEM = 4; unsigned short da1[N_ELEM]; unsigned short da2[N_ELEM]; bool SetArrayElem (unsigned short myStructure::**ptr , unsigned short index, unsigned short data) { if ((data <= 10) && (index < N_ELEM)) { this->*ptr[index] = data; return true; } else { return false; } } } st {};
调用st.SetArrayElem (&myStructure::da1, 2, 5);时编译报错:
<source>: In function 'int main()': <source>:20:22: error: cannot convert 'short unsigned int (myStructure::*)[4]' to 'short unsigned int myStructure::**' 20 | st.SetArrayElem (&myStructure::da1, 2, 5); | ^~~~~~~~~~~~~~~~~ | | | short unsigned int (myStructure::*)[4]
改成unsigned short myStructure::*ptr[4]还是报错,请问怎么正确实现处理数组成员的通用setter?
错误原因分析
你当前的参数类型声明错误:unsigned short myStructure::**ptr是指向“指向结构体成员的指针”的指针,而&myStructure::da1的类型是unsigned short (myStructure::*)[N_ELEM]——也就是指向结构体中固定大小数组成员的指针,两者类型不匹配,所以编译报错。
正确实现方案
要处理数组成员,需要把参数声明为指向数组类型的结构体成员指针,然后通过正确的语法访问数组元素:
方案1:直接使用固定大小数组的成员指针
#include <iostream> struct myStructure { static const int N_ELEM = 4; unsigned short da1[N_ELEM]; unsigned short da2[N_ELEM]; // 参数类型为:指向结构体中N_ELEM大小unsigned short数组的成员指针 bool SetArrayElem(unsigned short (myStructure::*arr_ptr)[N_ELEM], unsigned short index, unsigned short data) { if (data <= 10 && index < N_ELEM) { // 先通过成员指针获取数组,再访问对应下标 (*(this->*arr_ptr))[index] = data; return true; } return false; } } st {}; int main() { st.SetArrayElem(&myStructure::da1, 2, 5); // 正常赋值 st.SetArrayElem(&myStructure::da2, 3, 15); // 15超出范围,返回false std::cout << st.da1[2] << ',' << st.da2[3]; // 输出 "5,0" return 0; }
方案2:用模板适配任意大小数组(可选)
如果后续需要支持不同大小的数组,可以用模板让方法更通用:
#include <iostream> struct myStructure { static const int N_ELEM = 4; unsigned short da1[N_ELEM]; unsigned short da2[6]; // 另一个不同大小的数组 template <size_t Size> bool SetArrayElem(unsigned short (myStructure::*arr_ptr)[Size], unsigned short index, unsigned short data) { if (data <= 10 && index < Size) { (*(this->*arr_ptr))[index] = data; return true; } return false; } } st {}; int main() { st.SetArrayElem(&myStructure::da1, 2, 5); st.SetArrayElem(&myStructure::da2, 4, 8); std::cout << st.da1[2] << ',' << st.da2[4]; // 输出 "5,8" return 0; }
关键语法说明
unsigned short (myStructure::*arr_ptr)[N_ELEM]:明确声明这是一个指向myStructure中unsigned short[N_ELEM]类型成员的指针,括号不能省略,否则会被解析成“指向unsigned short的结构体成员指针构成的数组”。(*(this->*arr_ptr))[index]:先通过this->*arr_ptr获取到结构体中的数组成员,再用*解引用(因为成员指针指向的是数组整体),最后通过[index]访问数组元素。
内容的提问来源于stack exchange,提问作者hdmi87
相关产品推荐
相关产品推荐

