Visual walkthrough — Iterators — input, output, forward, bidirectional, random access, contiguous
5.2.21 · D2· Coding › C++ Programming › Iterators — input, output, forward, bidirectional, random ac
Yahan sab kuch the parent topic pe build hota hai. Agar koi word naya lage, hum use wahi define kar denge jab woh aaye.
Step 1 — Ek pointer ek row of boxes pe finger hai
YE YAHAN SE KYUN SHURU KARTE HAIN? Kyunki parent ke khud ke words ke mutabik har iterator ek generalized pointer hai. Agar hum exactly samjhein ki ek raw pointer ke paas kaun se powers hain, toh baad mein hum ek-ek karke puch sakte hain, "in mein se kaun si powers ek weird container afford kar sakta hai?" Yahi sawaal poori hierarchy generate karta hai.
PICTURE — finger, jo box woh open karta hai, aur slide-right move:

Raw-pointer version ke liye dekho Pointers and pointer arithmetic.
Step 2 — Powers hatao: one-way stream (Input & Output)
YEH KYUN MATTER KARTA HAI? Yeh dikhata hai ki har source dono atomic powers fully afford nahi kar sakta. Stream ++ (agle drop pe advance) rakhta hai lekin use cripple karta hai: advance karna purani position destroy kar deta hai. Aur yeh * ko do mutually exclusive halves mein baant deta hai:
- Input iterator: tum drop sirf read kar sakte ho —
x = *it. (Ek input stream.) - Output iterator: tum drop sirf write kar sakte ho —
*it = x. (Ek output stream/printer.)
"Tum har spot se sirf ek baar guzar sakte ho" ko single-pass kehte hain. Iterator ki ek copy purani jagah save nahi karti, kyunki underlying stream already move ho gayi.
PICTURE — ek drop pakda, phir gaya; note karo koi arrow baayein nahi point kar raha:

Step 3 — Past ki memory restore karo: multi-pass (Forward)
Yeh nayi power multi-pass kehlati hai: same element ke do iterators identically behave karte hain, aur re-traversal allowed hai. Yahi Forward category ka essence hai.
YEH GENUINELY EK NAYA RUNG KYUN HAI? Kyunki Step 2 mein ek copy bekar thi (stream move ho gayi). Yahan copy ek asli bookmark hai. Yeh ek farq — kya ek saved copy valid rehti hai? — exactly woh line hai jo Input/Output aur Forward ke beech hai.
PICTURE — "next" arrows se jude scattered boxes ki chain; ek bookmark copy same box pe wapas aati hai:

Step 4 — Chain ko peeche bhi follow karo (Bidirectional)
ABHI KYUN? Ek singly-linked chain (Step 3) --it cheaply nahi offer kar sakti — koi back-link nahi hai follow karne ke liye; tumhe front se restart karna padega, jo hai. Back-pointer add karo aur --it ho jaata hai. To container ka physical layout (kya har node apna predecessor jaanta hai?) decide karta hai ki Bidirectional affordable hai ya nahi.
PICTURE — same chain, ab forward aur backward dono links ke saath; finger dono taraf ja sakti hai:

Step 5 — Elements ek regular grid pe: the jump (RandomAccess)
REGULARITY YEH SAB EK SAATH KYUN UNLOCK KARTA HAI? Ye sab ek index pe arithmetic hai. Jis pal container tumhe ek index-to-position map de sakta hai jo ho, addition, subtraction, indexing, aur ordering sab ek saath nikal aate hain. Isliye ye ek single bundle ke roop mein enter karte hain.
PICTURE — ek finger boxes ke upar ek green arc mein leap karti hai, aur do fingers jinka gap measure kiya gaya hai:

Step 6 — Memory ka ek unbroken block: C-pointer promise (Contiguous)
YEH RANDOMACCESS SE ZYADA STRONG KYUN HAI? deque ke saath, element 5 aur element 6 alag chunks mein reh sakte hain, to unke memory addresses +1 se related nahi hain. Index mein distance compute karna hai, lekin bytes mein distance unpredictable hai. Contiguous gaps ko forbid karta hai, deta hai:
Har symbol: &*it iterator leta hai, uska box kholta hai (*), aur us box ka real address maangta hai (&); equation kehti hai aage step karna address ko exactly elements se move karta hai — memory mein ek seedhi line. Yahi cheez tumhe &v[0] ek C API ko pass karne deti hai jo bare double* expect karta hai.
PICTURE — deque ke gappy chunks (addresses jump karte hain) versus vector ka solid block (addresses march karte hain):

Step 7 — Degenerate cases (koi scenario kabhi mat chodo)
PICTURE — empty range jahan begin aur end milte hain, aur count-driven output bina sentinel ke:

Step 8 — Compiler yeh ladder kaise padhta hai: tag dispatch
TAGS KYUN AUR if KYUN NAHI? Ek if (is_random_access) ek runtime check ka cost lagaata aur saath hi list ke liye bhi it += n compile karne ki koshish karta (jo support nahi karta → error). Tag compiler ko illegal branch discard karne deta hai completely: zero runtime cost, sirf legal code compile hota hai. Yahi hierarchy ka poora payoff hai.
PICTURE — ek call tag type se correct overload pe fan out karti hai:

Machinery ke baare mein aur: Templates and Tag Dispatch aur iterator_traits and type introspection. Iska modern face hai Ranges library (C++20).
Ek-picture summary

Recall Feynman retelling — plain words mein batao
Socho ek finger boxes ki shelf pe. Ek box kholo (*), daayein slide karo (++) — yeh ek pointer hai, aur yeh sab kuch ka seed hai.
Ab ise kamzor karo: ek stream sirf ek baar har item pakadne deta hai jab woh flow kare — read-only ya write-only, single-pass. Yahi hai Input/Output, floor.
Items ko real memory mein rakho aur ek saved bookmark ko valid rehne do — ab tum revisit aur re-read kar sakte ho. Yahi hai Forward.
Har item ko ek link do us item ka jo pehle tha, aur finger baayein slide kar sakti hai. Yahi hai Bidirectional (--it).
Items ko ek regular grid pe space karo taaki unki positions computable hon, aur finger ek saath boxes leap kar sake, gaps measure kar sake, aur positions compare kar sake — sab ek step mein. Yahi hai RandomAccess.
Aakhir mein, saare gaps forbid karo taaki items ek solid block mein baith jaayein; tab iterator math real address math ke barabar ho jaata hai aur tum start ko ek C function ko de sakte ho. Yahi hai Contiguous.
Yeh ladder exist karta hi isliye hai: har nayi power tabhi affordable hai jab container ka physical layout use support kare. Aur compiler ek tiny empty tag se padhta hai tum kis rung pe ho, zero runtime cost ke saath sabse fast legal code choose karta hai.
Recall
Woh single fact jo poori hierarchy generate karta hai... ::: container ka physical memory layout — woh jo cheaply kar sakta hai wahi decide karta hai ki woh kaun si powers offer karta hai.
Input/Output aur Forward ke beech line hai... ::: kya iterator ki saved copy valid rehti hai (multi-pass).
Bidirectional aur RandomAccess ke beech line hai... ::: kya tum baar step karne ki jagah mein it+n jump kar sakte ho.
RandomAccess aur Contiguous ke beech line hai... ::: kya &*(it+n) == &*it + n (ek unbroken memory block).
Tag dispatch sahi overload choose karta hai... ::: compile time pe, iterator ke category tag type se — zero runtime cost.