std::ranges、std::views和懒加载
1、std::string::npos是C中std::string类定义的一个静态常量通常用于表示“未找到”或“直到字符串结束”。常见用途表示查找操作但未找到结果std::string str hello word; size_t pos str.find(xyz); if(pos std::string::npos) { //查到结尾但未找到 }表示从某个位置开始截取到字符串末尾std::string str hello world; std::string sub str.substr(6,std::string::npos); //表示从位置6开始截取到字符串末尾2、惰性视图是一种优化程序性能的编程技术。它的核心理念是把要做的工作记录下来但不立即执行等到需要结果的那一刻才进行真正的计算。3、C20引入的Ranges库是标准库模板STL的一次重大升级它通过“视图”和“管道符 |”提供了一种更现代、更强大、也更安全的数据处理方式。核心概念Ranges库建立在几个相互关联的核心概念之上1范围一个可以遍历的元素序列的抽象。如标准容器库vector,list,array等都是范围2视图一个轻量级的、非持有的范围它不会复制数据而是对底层数据进行某种操作如筛选、转换等并提供一个“视图”。视图的计算是惰性的即只有在需要时才计算这为性能优化提供了巨大空间。3范围适配器返回视图的函数或对象。它们是构建数据处理管道的基本单元通过管道符 | 进行组合数据从左向右流动逻辑清晰直观。4管道符用于组合视图的操作符。R | A | B的写法让数据处理像流水线一样易于理解。Ranges库并非仅仅是语法糖它代表了一种全新的、更函数式的C编程范式。#include string #include vector #include algorithm #include ranges #include iostream int main() { std::string word apple; auto hasWord [word](const std::string s) {return s.find(word) ! std::string::npos;}; std::vectorstd::string words { apple pie, banana split, apple tart, cherry cobbler }; auto res words | std::views::filter(hasWord); for (auto s : res) { std::cout s std::endl; } std::vectorint input{0,1,2,3,4,5,6,7,8,9,10}; std::vectorint intermediate, output; std::copy_if(input.begin(), input.end(), std::back_inserter(intermediate), [](int i) {return i % 3 0; }); std::transform(input.begin(), input.end(), std::back_inserter(output), [](const int i) {return i * i; }); for (auto i : intermediate) { std::cout i ; } std::cout std::endl; for (auto i : output) { std::cout i ; } std::cout std::endl; auto output2 input | std::views::filter([](const int i) {return i % 3 0; }); auto output3 input | std::views::transform([](const int i) {return i * i; }); for (auto i : output2) { std::cout i ; } std::cout std::endl; for (auto i : output3) { std::cout i ; } std::cout std::endl; auto output4 input | std::views::filter([](const int i) {return i % 3 0; }) | std::views::transform([](const int i) {return i * i; }); std::cout ------------------ std::endl; for (auto i : output4) { std::cout i ; } std::cout std::endl; return 0; }4、管道的作用左边数据源容器、范围右边视图适配器效果将数据源“喂给”视图适配器处理5、懒加载的具体体现#include iostream #include vector #include string #include ranges int main() { std::vectorstd::string words { apple pie, banana split, apple tart }; int filterCalls 0; auto hasApple [filterCalls](const std::string s) { filterCalls; std::cout Filter checking: s std::endl; return s.find(apple) ! std::string::npos; }; // 创建视图 - 不会触发任何过滤检查 auto view words | std::views::filter(hasApple); std::cout After view creation, filter calls: filterCalls std::endl; // 第一次遍历 - 触发过滤 std::cout \nFirst iteration:\n; for (const auto s : view) { std::cout Result: s std::endl; } std::cout Filter calls after first iteration: filterCalls std::endl; // 第二次遍历 - 再次触发过滤 std::cout \nSecond iteration:\n; for (const auto s : view) { std::cout Result: s std::endl; } std::cout Filter calls after second iteration: filterCalls std::endl; }与普通容器相比#include iostream #include vector #include string #include ranges int main() { std::vectorstd::string words {apple pie, banana split, apple tart}; // 方式1立即求值的传统方式 auto hasApple [](const std::string s) { return s.find(apple) ! std::string::npos; }; std::vectorstd::string eager_result; std::copy_if(words.begin(), words.end(), std::back_inserter(eager_result), hasApple); // eager_result 现在就包含了所有匹配的字符串副本 // 方式2惰性求值的视图方式 auto lazy_view words | std::views::filter(hasApple); // lazy_view 不包含数据只是知道如何过滤 // 主要区别 // 1. 内存eager_result 占用额外内存lazy_view 不占用 // 2. 时间eager_result 立即计算lazy_view 延迟计算 // 3. 原数据修改lazy_view 会反映原数据的变化 }