C++实现支持任意数量多类型参数的键盘输入函数getValues
可行性结论
该需求完全可以实现,你的可行性判断正确,使用现代C++的可变参数特性即可写出完全匹配示例调用方式的函数,不需要修改调用侧代码。
具体实现方案
优先推荐使用C++11及后续标准支持的可变参数模板实现,该方案类型安全,写法和你预期的调用形式完全一致。
方式1:兼容C++11的递归展开实现
可变参数模板通过递归逐次处理每一个传入的引用参数,直到所有参数处理完毕,需要单独写无参的递归终止函数。
完整示例代码:
#include <iostream> #include <string> // 递归终止条件:无剩余参数待处理时直接返回 void getValues() {} template<typename T, typename... Args> void getValues(T& cur_val, Args&... rest_vals) { // 从标准输入读取值赋值给当前参数 std::cin >> cur_val; // 递归处理剩余参数 getValues(rest_vals...); } int main() { int a; float b; char c; std::string d; // 和你给出的调用写法完全一致 getValues(a, b, c, d); // 测试输出验证赋值结果 std::cout << "a=" << a << ", b=" << b << ", c=" << c << ", d=" << d << std::endl; return 0; }
实现说明
- 函数形参全部采用引用传递,保证读取到的值可以直接修改外部传入的原变量
- 输入分割规则和原生
std::cin完全一致,默认以空格、换行、制表符作为输入值的分隔符 - 传入参数的类型没有额外限制,只要是
std::cin原生支持读取的类型(包括自定义重载了>>运算符的自定义类型)都可以正常传入
方式2:C++17及以上更简洁的折叠表达式实现
如果你的编译环境支持C++17标准,可以直接用折叠表达式省略递归逻辑,代码更短小:
#include <iostream> #include <string> template<typename... Args> void getValues(Args&... args) { // 折叠表达式批量执行输入操作 (std::cin >> ... >> args); } // 调用方式和之前完全一致 int main() { int a; float b; char c; std::string d; getValues(a, b, c, d); return 0; }
注意事项
- 不要传入常量、临时对象等右值作为参数,函数需要修改原变量的值,只接受有实际存储的左值变量
- 如果需要读取包含空格的字符串,不要直接用这个版本的实现,需要单独针对
std::string类型重载逻辑,改用std::getline读取 - 输入值的类型、顺序需要和传入变量的顺序、类型匹配,否则会触发
std::cin的错误状态,和原生输入行为一致,有需要可以自行在函数内添加输入错误处理逻辑 - 不推荐使用C风格的
va_list可变参数实现该功能,该方式无法自动推导参数类型和个数,需要手动传入参数数量、类型标记,存在类型安全隐患,也无法匹配你给出的简洁调用形式。
内容的提问来源于stack exchange,提问作者Ales1297
相关产品推荐
相关产品推荐

