我正试图实现一个简单的菜单类,以便在编程AVR板时灵活使用。因此,我不能使用几个常用的STL文件(如? functional
或 initializer_list
等)。)
我的菜单对象有指向上一个和下一个对象的指针,但也有在某些情况下执行的函数指针。我在这些指针上遇到了问题。
我设法用一个单一的函数指针让所有的东西都能工作。然而,当我试图使用一个函数指针数组时,我无法找到一种方法来初始化它。请看下面的最小例子或在 onlinegdb.com. 为了简单起见,我把数组大小硬编码为2。
错误信息
error: incompatible types in assignment of ‘void (**)()’ to ‘void (* [2])()’
为什么同样的语法 tFcnPtr[2]
给出两种不同的类型?
构造函数参数变成了 void (**)()
而成员的定义是 void (* [2])()
.
函数指针 typedef
typedef void(*tFcnPtr)();
tMenu类 (效果不错!)
class tMenu {
public:
tMenu(tFcnPtr ptr) : _ptr(ptr) {}
void run() {
_ptr();
}
tFcnPtr _ptr;
};
tMenu2类,但这并不奏效。我无法成功初始化函数指针数组。
class tMenu2 {
public:
tMenu2(tFcnPtr ptrs[2]) : _ptrs(ptrs) {} // error: incompatible types in assignment of ‘void (**)()’ to ‘void (* [2])()’
void run() {
for (auto& fcn : _ptrs) {
if (fcn != nullptr) {
fcn();
}
}
}
tFcnPtr _ptrs[2];
};
测试
// Main test function
void p(const char c[]) {
std::cout << c << std::endl;
}
// Main
int main()
{
// Test functions
tFcnPtr yup = [](){p("Yup!");};
tFcnPtr zup = [](){p("Zup!");};
tFcnPtr meh = [](){p("Meh.");};
// tMenu
tMenu m1{yup};
m1.run();
std::cout << std::endl;
// tMenu2
tFcnPtr ptrs[] = {zup, meh};
tMenu2 m2{ptrs};
m2.run();
}
事实上 功能参数 ptrs
的类型不是一个 阵列但 指针 (即 tFcnPtr *
),不能直接用来初始化一个数组。这就是编译器的抱怨。
参数列表中每个函数参数的类型是根据以下规则确定的。
2)如果类型是 "数组的
T
"或 "未知边界的数组T
",它被 "指向的指针 "所取代。T
"
你可以将数组成员初始化为
class tMenu2 {
public:
tMenu2(tFcnPtr ptrs[2]) : _ptrs{ptrs[0], ptrs[1]} {}
...
tFcnPtr _ptrs[2];
};
或使用 std::array
(或 std::vector
如果大小不固定)代替。
class tMenu2 {
public:
tMenu2(std::array<tFcnPtr, 2> ptrs) : _ptrs(ptrs) {}
...
std::array<tFcnPtr, 2> _ptrs;
};