遍历函数指针vector时,显式替代auto的正确语法是什么?
函数指针vector遍历的显式类型语法问题
我有一个存储函数指针的vector,遍历代码如下:
vector<int (*)(int, int)>v; //... push_back 一些函数指针 for (auto func : v) { /* 执行操作 */ }
出于学习目的,我想把auto替换成它推导出的显式类型,于是尝试了这样的写法:
for (int (*)(int, int) func : v) { /* ... */} // [1]
但编译器报错"Expected an identifier"。可下面这段用类型别名的写法却能正常编译:
using funcZ2toZ = int (*)(int, int); for (funcZ2toZ func : v) { /* ... */ }
请问[1]行的正确语法是什么?
问题原因与解决方案
问题出在C的声明语法规则上:函数指针属于复合类型,不能直接以完整复合类型 变量名的形式写在range-based for循环的初始化部分,必须遵循C声明的"嵌入式"语法——把变量名嵌入到类型的符号结构中。
正确写法1:嵌入变量名到函数指针类型中
把变量名func放到括号内,明确它是指针的主体:
for (int (*func)(int, int) : v) { /* ... */ }
这种写法完全遵循C++声明函数指针的语法:int (*func)(int, int)本身就是一个合法的函数指针声明,放在循环里自然符合语法要求。
正确写法2:使用decltype自动推导元素类型
如果不想手动书写复杂的函数指针类型,可以用decltype直接获取容器元素的类型:
for (decltype(v.front()) func : v) { /* ... */ }
或者更通用的decltype(*v.begin()),对于非空的vector来说,v.front()的类型就是容器的元素类型,简洁又准确。
为什么类型别名的写法可行?
using定义的funcZ2toZ是一个单一的标识符类型,本质上是把复杂的函数指针类型包装成了一个普通的"类标识符",符合range-based for循环中类型名 变量名的基础语法结构,所以编译器可以正常解析。
内容的提问来源于stack exchange,提问作者butterflyknife
相关产品推荐
相关产品推荐

