如何用STL算法生成未知大小的动态容器?
用STL算法生成元素数量未知的容器
完全理解你想摆脱手动循环、写出更优雅安全代码的想法——Kate Gregory在《Beautiful C++》里强调的表达性和安全性确实是现代C的核心追求之一。针对元素数量未知的场景,我们可以根据你使用的C版本选择不同的STL风格方案:
C++20及以上:用范围库实现最优雅的写法
C++20引入的范围视图是处理这类问题的最佳工具,它能让你用声明式的方式描述"生成元素直到满足某个条件"的逻辑,完全无需手动循环:
#include <vector> #include <ranges> #include <algorithm> #include <random> int main() { // 示例:生成随机数,直到生成的数大于0.9为止 std::mt19937 rng(std::random_device{}()); std::uniform_real_distribution<double> dist(0.0, 1.0); // 用视图链描述生成逻辑:无限生成随机数 → 取到第一个大于0.9的数之前的所有元素 auto random_sequence = std::views::generate([&]() { return dist(rng); }) | std::views::take_while([](double x) { return x <= 0.9; }); // 将视图转换为容器 std::vector<double> dynamic_container(random_sequence.begin(), random_sequence.end()); return 0; }
这里std::views::generate负责无限生成元素,std::views::take_while负责过滤出满足条件的元素,最后直接用容器的范围构造函数完成转换,代码逻辑清晰且完全符合STL风格。
C11到C17:封装生成逻辑避免重复循环
如果还没升级到C++20,我们可以封装一个简单的工具函数,把循环逻辑隐藏起来,调用时依然保持STL式的表达性:
#include <vector> #include <algorithm> #include <random> #include <functional> // 封装:生成元素直到停止条件满足,自动插入到容器中 template<typename Container, typename Generator, typename Predicate> void generate_until(Container& container, Generator gen, Predicate stop_pred) { while (true) { auto value = gen(); if (stop_pred(value)) { break; } container.push_back(std::move(value)); } } int main() { std::mt19937 rng(std::random_device{}()); std::uniform_real_distribution<double> dist(0.0, 1.0); std::vector<double> dynamic_container; // 调用时只需关注生成逻辑和停止条件,无需写循环 generate_until(dynamic_container, [&]() { return dist(rng); }, [](double x) { return x > 0.9; }); return 0; }
这个工具函数只需要写一次,后续调用时可以像使用STL算法一样简洁,同时避免了手动循环可能带来的边界错误。
特殊场景:从输入流读取未知数量元素
如果你的元素来自输入流(比如文件、标准输入),可以直接用std::copy搭配std::istream_iterator,完全无需手动处理循环:
#include <vector> #include <algorithm> #include <fstream> #include <iterator> int main() { std::ifstream input_file("numbers.txt"); std::vector<int> dynamic_container; // 从文件读取所有int元素,直到流结束 std::copy(std::istream_iterator<int>(input_file), std::istream_iterator<int>(), std::back_inserter(dynamic_container)); return 0; }
这些方案的核心都是把循环逻辑交给STL或封装好的工具,让你的代码专注于业务逻辑,既提高了可读性,也减少了出错的可能,完美契合你追求的"Beautiful C++"风格。
内容的提问来源于stack exchange,提问作者PrancingCrabulon
相关产品推荐
相关产品推荐

