Exercises — Template specialization — full and partial
5.2.15 · D4· Coding › C++ Programming › Template specialization — full and partial
Vocabulary reminder (sab parent note mein build kiye gaye hain):
- Primary template — generic fallback recipe.
- Full specialization —
template<>jisme exact type pin ki gayi ho, jaiseBox<int>. - Partial specialization — ek shape pin ki gayi ho (jaise
T*yapair<A,B>), kuch params abhi bhi free hon. - Compiler most specialized matching pattern choose karta hai; agar tie ho aur koi winner na ho toh ambiguity error aata hai.
Level 1 — Recognition
Recall Solution 1.1
- (a) primary — ek free parameter
Thai, name pe koi pattern nahi. - (b) full —
template<>(zero free params), exact typeintpin ki gayi. - (c) partial —
Tabhi bhi free hai lekin shapeT*pin ki gayi hai. - (d) primary — do free params hain, koi pattern nahi.
- (e) partial — pehla param
intpe pin kiya gaya,Babhi bhi free hai.
Recall Solution 1.2
- (i) legal hai — function templates ko fully specialize kiya ja sakta hai.
- (ii) illegal hai — function templates ko partially specialize nahi kiya ja sakta. Iske liye aap overload
template<class T> void f(T*)use karte (dekho Overload Resolution vs Specialization).
Level 2 — Application
Recall Solution 2.1
- (a)
doublekisi pattern se match nahi karta → primary →0. - (b)
charfull specS<char>se match karta hai →1. - (c)
char*— kya yehS<char>se match karta hai? Nahi,char*charnahi hai. YehS<T*>seT=charke saath match karta hai →2. - (d)
int**ek pointer hai (toint*), tohS<T*>fire hogaT=int*ke saath →2.
Answers: 0, 1, 2, 2.
Recall Solution 2.2
template<class T> struct Unwrap<T*> { using type = T; };Unwrap<int**> ke liye: pattern T* match hoga T = int* ke saath, toh ::type hai int* — yeh sirf ek level of pointer strip karta hai, sab nahi. Fully strip karne ke liye recursion chahiye hoga, lekin yeh is single spec se pare hai.
Level 3 — Analysis
Recall Solution 3.1
- (a)
<double,char>sirf primary se match karta hai →0. - (b)
<double,int>sirfM<A,int>se match karta hai →1. - (c)
<int,double>sirfM<int,B>se match karta hai →2. - (d)
<int,int>M<A,int>,M<int,B>, aurM<int,int>teeno se match karta hai. Lekin full specializationM<int,int>sabse specific hai aur seedha jeet jaata hai →3.
Answers: 0, 1, 2, 3. Note: agar M<int,int> (full spec) ki line na hoti, toh case (d) ambiguity error hota kyunki M<A,int> aur M<int,B> tie karte.
Recall Solution 3.2
P1 (<A,int>) aur P2 (<T,T>) dono N<int,int> se match karte hain. Tie todne ke liye poochho: kya ek pattern strictly more specialized hai (dusre ka subset match karta hai)?
- P1 har
<X,int>se match karta hai; P2 har<X,X>se match karta hai. Na koi set dusre mein contained hai (jaise<double,int>P1 se match karta hai P2 se nahi;<char,char>P2 se match karta hai P1 se nahi). - Toh na koi zyada specialized hai → ambiguity error.
Level 4 — Synthesis
Recall Solution 4.1
template<class T> struct RemoveConst { using type = T; };
template<class T> struct RemoveConst<const T> { using type = T; };RemoveConst<const int>partialconst TseT=intke saath match karta hai →::type=int.RemoveConst<int>sirf primary se match karta hai →::type=int.
Yeh exactly waise hi build hota hai jaise std::remove_const — dekho Type Traits and std::is_pointer.
Recall Solution 4.2
template<class T> struct Rank { static const int value = 0; };
template<class T> struct Rank<T[]> { static const int value = 1 + Rank<T>::value; };
template<class T, unsigned N> struct Rank<T[N]> { static const int value = 1 + Rank<T>::value; };int[][3] ke liye trace (ek array of int[3], unknown outer size):
Rank<T[]>se match hogaT = int[3]ke saath →value = 1 + Rank<int[3]>::value.Rank<int[3]>Rank<T[N]>se match karta haiT=int, N=3ke saath →value = 1 + Rank<int>::value.Rank<int>primary se match karta hai →0.- Unwind:
1 + (1 + 0) = 2. ✓
Level 5 — Mastery
Recall Solution 5.1
Ill-formed program. Ek specialization type ki pehli instantiation se pehle aani chahiye. Yahan Traits<int> Traits<int> a; pe instantiate ho jaata hai, phir specialize kiya jaata hai — compiler pehle hi primary commit kar chuka tha (id = 0). Student jo value chahta tha woh thi 9, lekin ordering violation se program ill-formed ho jaata hai (diagnostic required hai).
Fix: template<> specialization ko Traits<int> a; se upar le jaao.
Recall Solution 5.2
- Way A legal hai (ek function template ki full spec allowed hai).
pick<int>()→1,pick<double>()→0. - Way B overload resolution pe rely karta hai:
pick2(int)(ek non-template exact match)intke liye template ko beat karta hai.pick2(5)→1,pick2(5.0)→0. - Functions ke liye best practice Way B (overloading) hai, kyunki functions ko partially specialize nahi kiya ja sakta; overloads wahi effect zyada predictably dete hain. Dekho Overload Resolution vs Specialization aur Tag Dispatch and Policy-based Design.
Recall Solution 5.3
Fmt<double>→ koi pattern nahi lekin primary hai →0.Fmt<double*>→Fmt<T*>se match karta hai (T=double);double*ke liye koi full spec nahi →1.Fmt<int*>→ primary se match? nahi.Fmt<T*>se? haan.Fmt<int*>full spec? haan — full wins →2.
Answers: 0, 1, 2.
Recall Master check — memory se karo
Selection order, ek line mein ::: full spec pehle → most-specialized partial → primary → warna ambiguity agar partials tie karein.
Fmt<int*> primary, T*, aur full int* ke saath ::: full int* jeet jaata hai.
Rank<int[][3]>::value ::: 2.
Functions ke liye Way B kyun ::: functions ko partially specialize nahi kiya ja sakta; overloads wahi effect predictably dete hain.