枚举值转整数直接初始化vector:哪种编译器实现符合标准?
枚举值初始化vector的编译器合规性分析
先看这段简化代码:
#include <vector> enum class E { Count }; int main() { std::vector<int*> vec( size_t( E::Count ) ); }
这段代码在GCC中可以正常编译运行,但Clang和MSVC都会报错:
- Clang错误提示:
error: parameter declarator cannot be qualified 6 | std::vector<int*> vec( size_t( E::Count ) );
- MSVC错误提示:
error C2751: 'E::Count': the name of a function parameter cannot be qualified
符合C++标准的是Clang和MSVC
问题出在C的**最令人头疼的解析(Most Vexing Parse)**规则:编译器会把vec(size_t(E::Count))解析成一个函数声明——即声明了一个名为vec的函数,返回std::vector<int*>类型,参数是一个名为E::Count、类型为size_t的形参。但根据C标准,函数参数的名称不能带有作用域限定符(E::这种写法),所以Clang和MSVC的报错是符合标准的行为。
GCC在这里做了非标准的扩展,绕过了歧义解析,将代码当作变量定义处理,这并不符合C++标准的要求。
修复方法
要消除这种解析歧义,有几种常见写法:
- 使用大括号初始化:
std::vector<int*> vec{ static_cast<size_t>(E::Count) };
- 给表达式额外加一层括号:
std::vector<int*> vec( (static_cast<size_t>(E::Count)) );
- 先把枚举值转换后存入变量再初始化:
size_t count = static_cast<size_t>(E::Count); std::vector<int*> vec(count);
内容的提问来源于stack exchange,提问作者Fedor
相关产品推荐
相关产品推荐

