#include <algorithm>#include <functional>#include <iostream>#include <ranges>#include <string> struct Pair{int n;std::string s;friendstd::ostream& operator<<(std::ostream& os,const Pair& p){return os<<'{'<< p.n<<", "<< p.s<<'}';}}; // A range-printer that can print projected (modified) elements of a range.template<std::ranges::input_range R,typename Projection= std::identity>//<- Notice the default projectionvoid print(std::string_viewconst rem, R&& range, Projection projection={}){std::cout<< rem<<'{'; std::ranges::for_each( range,[O=0](constauto& o) mutable{std::cout<<(O++?", ":"")<< o;}, projection);std::cout<<"}\n";} int main(){constauto v={Pair{1,"one"},{2,"two"},{3,"three"}}; print("Print using std::identity as a projection: ", v); print("Project the Pair::n: ", v,&Pair::n); print("Project the Pair::s: ", v,&Pair::s); print("Print using custom closure as a projection: ", v,[](Pairconst& p){returnstd::to_string(p.n)+':'+ p.s;});}