C++多枚举输入获取与校验的代码优化方案咨询
优化多枚举设置项的用户输入逻辑(消除重复代码)
问题描述
我需要处理多个作为程序设置项的枚举类型,要求逐个获取用户输入,且针对每个设置项持续请求直到输入合法,但当前实现存在大量重复代码,有没有更优的实现方式?
原代码
#include <iostream> #include <limits> enum Input1 {Type1 = 1, Type2 = 2, Type3 = 3, Type4 = 4}; enum Input2 {Type11 = 5, Type22 = 17}; bool validate_input(Input1 input1, Input2 input2 = Type11) { if(input1 != Type1 && input1 != Type2 && input1 != Type3 && input1 != Type4) { return false; } if(input2 != Type11 && input2 != Type22) { return false; } return true; } int main() { int iInput1, iInput2, iInput3; Input1 eInput1; Input2 eInput2; bool return_val; do { std::cout << "Select option: 1. 2. 3. 4."; std::cin >> iInput1; if (std::cin.fail()) { std::cin.clear(); std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n'); } eInput1 = (Input1) iInput1; return_val = validate_input(eInput1); if (!return_val) { std::cout << "Invalid input!\n"; } } while (!return_val); do { std::cout << "Select option: 1. 2."; std::cin >> iInput2; if (std::cin.fail()) { std::cin.clear(); std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n'); } eInput2 = (Input2) iInput2; return_val = validate_input(eInput1, eInput2); if (!return_val) { std::cout << "Invalid input!\n"; } } while (!return_val); return 0; }
原代码问题分析
- 两个输入循环逻辑几乎完全重复,仅提示文本、输入变量、验证逻辑不同,代码冗余严重。
validate_input函数同时绑定两个枚举的验证逻辑,耦合度高,无法单独复用某一个枚举的验证规则。- 第二个输入的提示文本与枚举实际值不匹配(提示1、2,但枚举值是5、17),会误导用户。
优化方案
核心思路是提取通用输入逻辑,将变化的部分(提示文本、验证规则、目标枚举类型)作为参数传入,彻底消除重复代码。
优化后的代码
#include <iostream> #include <limits> #include <functional> // 定义枚举类型 enum Input1 {Type1 = 1, Type2 = 2, Type3 = 3, Type4 = 4}; enum Input2 {Type11 = 5, Type22 = 17}; // 为每个枚举单独实现验证函数,降低耦合 bool validate_input1(Input1 input) { return input == Type1 || input == Type2 || input == Type3 || input == Type4; } bool validate_input2(Input2 input) { return input == Type11 || input == Type22; } // 通用输入获取模板函数:封装所有重复的输入循环逻辑 template<typename EnumType> EnumType get_valid_input(const std::string& prompt, const std::function<bool(EnumType)>& validator) { int raw_input; bool is_valid; EnumType enum_input; do { std::cout << prompt; std::cin >> raw_input; // 统一处理输入失败(如输入非数字) if (std::cin.fail()) { std::cin.clear(); std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n'); is_valid = false; std::cout << "Invalid input!\n"; continue; } enum_input = static_cast<EnumType>(raw_input); is_valid = validator(enum_input); if (!is_valid) { std::cout << "Invalid input!\n"; } } while (!is_valid); return enum_input; } int main() { // 调用通用函数获取合法输入,无需重复编写循环 Input1 eInput1 = get_valid_input<Input1>( "Select option: 1. 2. 3. 4.\n", validate_input1 ); Input2 eInput2 = get_valid_input<Input2>( "Select option: 5. 17.\n", validate_input2 ); // 新增其他枚举输入时,只需添加对应验证函数并调用get_valid_input即可 return 0; }
优化点说明
- 拆分验证逻辑:将原来的混合验证拆分为单个枚举的专属验证函数,每个函数只负责对应枚举的合法性检查,耦合度大幅降低。
- 通用输入函数:通过模板函数封装了输入循环的所有通用逻辑(提示输出、输入读取、错误处理、合法性验证、循环重试),变化部分通过参数传递,彻底消除重复代码。
- 修复提示错误:修正了原代码中第二个输入的提示文本,使其与枚举实际值匹配,避免误导用户。
- 扩展性强:后续新增枚举类型时,只需添加对应的验证函数,直接调用
get_valid_input即可,无需重复编写循环代码。
进一步优化方向
如果需要更灵活的验证规则,可以将验证器改为接受合法值集合,例如:
template<typename EnumType> EnumType get_valid_input(const std::string& prompt, const std::initializer_list<EnumType>& valid_values) { int raw_input; bool is_valid; EnumType enum_input; do { std::cout << prompt; std::cin >> raw_input; if (std::cin.fail()) { std::cin.clear(); std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n'); is_valid = false; std::cout << "Invalid input!\n"; continue; } enum_input = static_cast<EnumType>(raw_input); // 检查输入是否在合法值集合中 is_valid = std::find(valid_values.begin(), valid_values.end(), enum_input) != valid_values.end(); if (!is_valid) { std::cout << "Invalid input!\n"; } } while (!is_valid); return enum_input; } // 调用方式 Input1 eInput1 = get_valid_input<Input1>( "Select option: 1. 2. 3. 4.\n", {Type1, Type2, Type3, Type4} );
内容的提问来源于stack exchange,提问作者ashamedgap
相关产品推荐
相关产品推荐

