Worked examples — Templates — function templates, class templates
5.2.14 · D3· Coding › C++ Programming › Templates — function templates, class templates
Prerequisites jo tum open rakhna chahte ho: Function Overloading, Type Deduction (auto), Compile-time vs Runtime, Template Specialization, Macros vs Templates, Generic Programming, STL Containers.
The scenario matrix
Templates mein koi "quadrants" nahi hote jaise angle problem mein hote hain — lekin inka ek fixed set of situations zaroor hota hai jo alag behave karte hain. Yeh har woh cell hai jo hume cover karni hai.
| # | Case class | Yeh jo question test karta hai | Covered by |
|---|---|---|---|
| A | Function template, clean deduction | Compiler args padhta hai, ek T dhundhta hai |
Ex 1 |
| B | Deduction conflict (degenerate input) | Do arg types → koi single T nahi |
Ex 2 |
| C | Explicit type argument | Tum deduction ko <...> se override karte ho |
Ex 3 |
| D | Class template, explicit <T> |
No constructor deduction (pre-C++17) | Ex 4 |
| E | Non-type parameter (compile-time value) | <> mein ek number, type nahi |
Ex 5 |
| F | Full specialization (ek type ke liye "galat" wala case) | Generic recipe ko override karo | Ex 6 |
| G | The linker trap (definition in .cpp) | Real-world debugging word problem | Ex 7 |
| H | Exam twist: overload vs template resolution | Kaun sa function actually call hota hai? | Ex 8 |
Neeche har example apne cell letter ke saath tagged hai.
Ex 1 — Cell A: function template, clean deduction
Forecast: Aage padhne se pehle har call ke liye T aur returned value guess karo.
- Sirf argument types dekho.
3aur7donointhain. Yeh step kyun? Deduction values ko ignore karta hai — yeh arguments ke types ko patternT a, T bse match karta hai. Dono slotsinthain, isliye ek hi candidate hai:T = int. - Instantiate karo. Compiler
int maximum(int, int)stamp out karta hai. Kyun? Tabhi real machine code exist karta hai — ek unused template compile hoke kuch nahi banta (Compile-time vs Runtime). - Body evaluate karo.
(3 > 7) ? 3 : 7→7. Kyun? Ternary bada wala pick karta hai. - Doosra call:
2.5,1.1donodoublehain →T = double, returns(2.5 > 1.1) ? 2.5 : 1.1 = 2.5.
Verify:
maximum(3,7)deta hai7(ekint);maximum(2.5,1.1)deta hai2.5(ekdouble). Sanity check: answer hamesha do inputs mein se ek hota hai, aur bada wala hota hai. ✓
Ex 2 — Cell B: deduction conflict (degenerate input)
Forecast: Kya yeh 3 return karta hai, 3.0, ya compile karne se mana kar deta hai?
- Arg 1 ko pattern se match karo:
3inthai →T = int. Kyun? Wahi deduction rule, pehle slot par apply kiya. - Arg 2 ko pattern se match karo:
2.5doublehai →T = double. Kyun? Doosra slot bhiThai, isliye yehT = doubledemand karta hai. - Reconcile karo.
Tko ek type hona chahiye, lekin step 1 keh raha haiintaur step 2 keh raha haidouble. Contradiction → compile error (runtime error nahi). Yeh step kyun? Template argument deduction kabhi conversions insert nahi karta; use har us slot mein exact type match chahiye joTuse karta hai. - Fix — ek
Tforce karo:maximum<double>(3, 2.5). AbT = doublefix hai, aur3andar jaate waqt3.0mein convert hota hai. Returns3.0. Conversion ab kyun allowed hai? JabThaath se pin ho jata hai, toh args ek knowndoubleparameter mein pass ho rahe hain — ordinary implicit conversion apply hoti hai.
Verify:
maximum(3, 2.5)→ compile nahi hota.maximum<double>(3, 2.5)→3.0, ekdouble. Sanity:3.0 > 2.5, isliye bada wala,3.0, return hota hai. ✓
Ex 3 — Cell C: explicit type argument jo answer badal deta hai
Forecast: Kya dono 3.5 hain? Ya ek truncate hota hai?
half(7): deduce karoT = int(arginthai). Kyun? Clean single-type deduction (Cell A machinery).T = intke saath body:7 / 2integer division hai →3. Yeh step kyun? Body mein likha2ekinthai; C++ meinint / intremainder discard karta hai. Template ne arithmetic rules nahi badle — usne sirfintchoose kiya.half<double>(7):Tforce karkedouble;7convert hota hai7.0mein. Kyun? Explicit<double>deduction override karta hai, bilkul Ex 2 ki fix ki tarah.T = doubleke saath body:7.0 / 2→3.5. Kyun?double / intmein2promote hota hai2.0mein, isliye real division hoti hai.
Verify:
half(7) == 3(integer division),half<double>(7) == 3.5. Dono alag hain chosenTki wajah se, algorithm ki wajah se nahi. ✓
Ex 4 — Cell D: class template ko explicit <T> chahiye
Forecast: Kya constructor ka 42 compiler ko T = int batata hai jaise maximum(42) batata?
- Fark yaad karo: function templates
Tdeduce karte hain arguments se; class templates (C++17 se pehle) constructor call se deduce nahi karte. Kyun? Function wahi cheez hai jo tum call karte ho, isliye uske args call par visible hote hain. Class ka naamBoxkisi bhi constructor consider hone se pehle ek complete type hona chahiye — pehle type known hona chahiye. Isliye naam lena padta hai:Box<int>. Box<int> b(42);likho. Compiler ek concrete classBox<int>generate karta hai jahan harTintban jaata hai. Kyun? Instantiation parameter ko puri class body mein replace karta hai.b.get()call karo: storedvaluereturn karta hai, jo hai42.- Type identity note karo:
Box<int>aurBox<double>unrelated types hain — tum ek ko doosre mein assign nahi kar sakte. Yahi rule hai jovector<int>aurvector<double>ko alag banata hai (STL Containers).
Verify:
Box<int> b(42); b.get()→42.Box b(42);pre-C++17 compile nahi hota. ✓
Ex 5 — Cell E: non-type template parameter
Forecast: Kya N ek aisi variable hai jo runtime par change ho sakti hai, ya yeh baked in hai?

- Parameters identify karo:
Tek type hai,Nek value hai — specifically ek compile-timeint(Compile-time vs Runtime). Yeh step kyun? Templates do flavours ke parameters accept karte hain.Nek type nahi hai, isliye yehint Nslot mein ek actual number fill karta hai. Figure dekho: violet<double, 5>cutter ke dono slots fill karta hai — ek type se, ek number se. Array<double, 5>instantiate karo. Abdataliterallydouble data[5]hai — ek fixed-size array, size program run hone se pehle known hai. Kyun matter karta hai? Kyunki5ek compile-time constant hai, array stack par rehta hai, koi heap allocation nahi, aur compiler sab kuch inline kar sakta hai.a.size()call karo:Nreturn karta hai, jise compiler ne pehle hi5se replace kar diya. Yeh ek compile-time constant hai, effectivelyreturn 5;.- Degenerate check — kya
N0ho sakta hai?Array<double, 0>legal-ish hai lekin zero-length array ek corner case hai (technically ill-formed for plainT data[0]); isse avoid karo. Yeh hamare matrix ka "zero input" cell hai.
Verify:
a.size() == 5, storagedouble[5]stack par hai (5 * 8 = 40bytes ek typical 8-byte-doubleplatform par). ✓
Ex 6 — Cell F: full specialization (ek type ke liye generic recipe galat hai)
Forecast: Kya dono "1" print karte hain? Ya bool alag behave karta hai?

Printer<int>::show(1)generic template use karta hai:to_string(1)→"1". Yeh step kyun?intke liye koi special version nahi hai, isliye compiler general cookie-cutter par fall back karta hai.Printer<bool>::show(true)— compiler exact-match specializationPrinter<bool>dekhta hai aur usse generic se prefer karta hai. Kyun? Sabse specialized matching template jeet ta hai (Template Specialization). Figure mein,boolorange arrow follow karke apni dedicated recipe tak jaata hai.- Specialized body run karo:
true ? "true" : "false"→"true". Kyun specialize kiya? Genericto_string(true)deta"1"— technically correct lekin woh human-readable word nahi jo hum chahte the. Specialization us ek type ko fix karta hai jo misbehave karta hai baaki ko touch kiye bina.
Verify:
Printer<int>::show(1) == "1",Printer<bool>::show(true) == "true",Printer<bool>::show(false) == "false". ✓
Ex 7 — Cell G: the linker trap (real-world word problem)
Forecast: Kya yeh syntax bug hai, runtime crash hai, ya linker problem hai? Padhne se pehle guess karo.
Stack<int>pehle use kahan hota hai?main.cppmein. Yeh step kyun? Instantiation use ke point par hoti hai.main.cppcompile karne wala compiler hi hai jiseStack<int>::pushgenerate karna hai.main.cppcompiler kya dekh sakta hai? Sirfstack.h(declaration).pushki bodystack.cppmein rehti hai, ek separate translation unit (Compile-time vs Runtime). Kyun matter karta hai? Body ke bina, compilerStack<int>::pushke liye ek call emit karta hai lekin function kabhi generate nahi karta — yeh assume karta hai koi aur unit karega.stack.cppkabhiStack<int>instantiate nahi karta (yeh kabhiintmention nahi karta), isliye koi code generate nahi karta → linker ek dangling reference dhundtha hai →undefined reference. "linker" kyun, "compiler" kyun nahi? Har file apne aap theek compile hui; mismatch tabhi dikhta hai jab object files together link ho rahe hote hain.- Cure: full template definition header (
.h/.hpp) mein daalo, taaki har file jo template use kare body dekhe aur instantiate kar sake. Multiple-definition errors se safe kyun hai? Template instantiations ko special linkage milta hai — alag units mein identical instantiations merge ho jaate hain, duplicate nahi hote.
Verify (conceptual): body
stack.hmein move karo →main.cppdekh leta hai →Stack<int>::pushgenerate hoti hai → link succeed karta hai. Bug ki class ek linker error hai, joundefined referencewording se confirm hoti hai. ✓
Ex 8 — Cell H: exam twist — overload vs template resolution
Forecast: Teen calls, teen answers. Har ek guess karo.
who(5): ek exact non-template matchwho(int)exist karta hai. Yeh step kyun? Jab ek normal (non-template) function equally good match ho, compiler non-template overload prefer karta hai (Function Overloading). Toh yeh"plain int"return karta hai.who(2.5): plainwho(int)kodouble → intconversion chahiye (worse match), lekinwho(T)withT = doubleek exact match hai. Kyun? Template ek exact type match deta hai; exact, conversion se better hota hai. Returns"template".who<int>(5):<int>explicitly template koT = intke saath demand karta hai, isliye plain overload primary ke taur par consider hi nahi hota — template jeet ta hai. Returns"template". Kyun? Tumne ek template argument name kiya, jo sirf ek template accept kar sakta hai, isliye overload resolution template path par force ho jaati hai.
Verify:
who(5) == "plain int",who(2.5) == "template",who<int>(5) == "template". Sanity:5ke liye exact-match plain function template ko beat karta hai;2.5ke liye template jeetta hai (ek narrowing conversion avoid karta hai) aur jab bhi tum<...>likhte ho. ✓
Recall Quick self-test
maximum(3, 2.5) fail kyun hota hai? ::: Deduction arg 1 se T=int deta hai aur arg 2 se T=double — ek T dono nahi ho sakta.
half(7) kya return karta hai? ::: 3, kyunki T=int se 7/2 integer division ho jaata hai.
half<double>(7) kya return karta hai? ::: 3.5, kyunki T=double se real division hoti hai.
Pre-C++17 mein Box b(42); ko Box<int> b(42); kyun banana padta hai? ::: Class templates T constructor se deduce nahi karte; pehle type name karni padti hai.
Printer<bool>::show(true) kya return karta hai? ::: "true", us full specialization se jo generic recipe ko override karti hai.
Template ke liye linker error undefined reference ka matlab? ::: Definition ek .cpp mein thi jo using file nahi dekh sakti thi; full body header mein daalo.
who(2.5) kya return karta hai? ::: "template" — exact template match, plain overload mein double→int conversion se better hai.