在构造函数初始化器列表中初始化函数指针数组 - 错误
Posted
技术标签:
【中文标题】在构造函数初始化器列表中初始化函数指针数组 - 错误【英文标题】:Initialize function pointer array in constructor initializer list - error 【发布时间】:2020-05-15 07:47:23 【问题描述】:我正在尝试实现一个简单的菜单类,以便在编程 AVR 板时灵活使用。因此,我无法使用几个常用的 STL 文件(例如 functional
或 initializer_list
等)。
我的菜单对象有指向前一个和下一个对象的指针,还有在某些情况下执行的函数指针。我对这些指针有疑问。
我设法用一个函数指针让一切工作。但是,当尝试使用函数指针数组时,我找不到初始化它的方法。请参阅下面或onlinegdb.com 上的最小示例。为简单起见,我将数组大小硬编码为 2。
错误信息
error: incompatible types in assignment of ‘void (**)()’ to ‘void (* [2])()’
为什么同一个语法tFcnPtr[2]
会给出两种不同的类型??
构造函数参数变为void (**)()
,而成员定义为void (* [2])()
。
函数指针类型定义
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 m1yup;
m1.run();
std::cout << std::endl;
// tMenu2
tFcnPtr ptrs[] = zup, meh;
tMenu2 m2ptrs;
m2.run();
【问题讨论】:
C++中没有数组类型的函数参数。您可以这样编写它,但编译器会默默地将类型衰减为指针。这是 C 的继承,被 C++ 接管。您可以使数组成为引用类型,例如而不是int a[2]
(衰减到int *a
)你可以写int (&a)[2]
。 (引用在 C 中不存在,而是在 C++ 中添加。)更方便和 C++-ish 将使用 std::array
代替。
关于参考的好提示,不知道它适用于函数和方法。很遗憾,我使用的编译器(avr-gcc/WIN-AVR)不支持she::array。
【参考方案1】:
其实function parameterptrs
的类型不是array,而是pointer(即tFcnPtr *
),不能用来直接初始化一个数组。这就是编译器所抱怨的。
参数列表中每个函数参数的类型根据以下规则确定:
2) 如果类型是“
T
的数组”或“T
的未知边界数组”,则替换为“指向T
的指针”类型
可以将数组成员初始化为
class tMenu2
public:
tMenu2(tFcnPtr ptrs[2]) : _ptrsptrs[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;
;
【讨论】:
哦,好吧。这是一个很好的解释。谢谢!我想要的是一种灵活的类型,它允许不同数量的指针。我认为不支持 std::array (我的编译器找不到 ),所以我想我必须创建自己的容器。没有大问题,但可能有问题? @Smartskaft2std::array
从 C++11 开始支持,如果你不能使用它,我认为使用 std::vector
是一个好主意。
如果不支持std::array
,我几乎不怀疑std::vector
支持。特别是因为动态内存在这些芯片上是一个很大的禁忌(没有太多可用的堆内存)。同样,这不是标准的 GCC 编译器。 avr-gcc 仅支持 C+11 的部分内容,对 STL 的支持不多。以上是关于在构造函数初始化器列表中初始化函数指针数组 - 错误的主要内容,如果未能解决你的问题,请参考以下文章