std::optional<vector<枚举>>赋值行为疑问:枚举触发大小构造?
现象说明
以下代码中,使用非enum class的枚举值通过列表初始化给std::optional<std::vector<Type>>赋值时,最终生成的vector大小等于枚举值对应的整数,而非包含单个枚举元素的vector:
enum Type { A, B, C }; int main(int argc, char** argv) { std::optional<std::vector<Type>> types; types = { A }; std::cout << types->size() << std::endl; // 输出0(A对应整数0) types = { C }; std::cout << types->size() << std::endl; // 输出2(C对应整数2) }
最初误以为types = {7}无法编译,实际是IntelliSense误报,该代码可正常编译并生成大小为7的vector。
而使用enum class(强类型枚举)时,行为符合预期,会创建包含单个枚举元素的vector:
enum class TypeClass { A, B, C }; int main(int argc, char** argv) { std::optional<std::vector<TypeClass>> types; types = { TypeClass::A }; // 创建包含1个元素的vector types = { TypeClass::C }; // 创建包含1个元素的vector }
原因分析
非强类型枚举的隐式转换特性
传统非enum class枚举支持隐式转换为整数类型,比如A对应整数0,C对应整数2。当用单个枚举值进行列表初始化时,编译器会将枚举值隐式转换为整数,进而匹配std::vector的大小构造函数:explicit vector(size_type n);,该构造函数会创建包含n个默认构造元素的vector。强类型枚举的强类型限制
enum class是强类型枚举,不允许隐式转换为整数。因此当用{TypeClass::A}赋值时,编译器只能匹配std::vector的初始化列表构造函数:vector(std::initializer_list<T>),最终创建包含单个枚举元素的vector,符合直觉预期。关于
types = {7}的编译问题int类型可以直接转换为std::vector的size_type(通常是size)...atcherAGA-n Tak侍者 Make该项Out NC的供给的类型),因此types = {7}可以正常编译,触发vector的大小构造函数。IntelliSense的误报是编辑器层面的问题,不代表实际编译行为。
内容的提问来源于stack exchange,提问作者Aedoro

