5.2.15 · D4 · HinglishC++ Programming

ExercisesTemplate specialization — full and partial

2,257 words10 min read↑ Read in English

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 specializationtemplate<> jisme exact type pin ki gayi ho, jaise Box<int>.
  • Partial specialization — ek shape pin ki gayi ho (jaise T* ya pair<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 T hai, name pe koi pattern nahi.
  • (b) fulltemplate<> (zero free params), exact type int pin ki gayi.
  • (c) partialT abhi bhi free hai lekin shape T* pin ki gayi hai.
  • (d) primary — do free params hain, koi pattern nahi.
  • (e) partial — pehla param int pe pin kiya gaya, B abhi 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) double kisi pattern se match nahi karta → primary0.
  • (b) char full spec S<char> se match karta hai → 1.
  • (c) char* — kya yeh S<char> se match karta hai? Nahi, char* char nahi hai. Yeh S<T*> se T=char ke saath match karta hai → 2.
  • (d) int** ek pointer hai (to int*), toh S<T*> fire hoga T=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> sirf M<A,int> se match karta hai → 1.
  • (c) <int,double> sirf M<int,B> se match karta hai → 2.
  • (d) <int,int> M<A,int>, M<int,B>, aur M<int,int> teeno se match karta hai. Lekin full specialization M<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 haiambiguity 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> partial const T se T=int ke 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):

  1. Rank<T[]> se match hoga T = int[3] ke saath → value = 1 + Rank<int[3]>::value.
  2. Rank<int[3]> Rank<T[N]> se match karta hai T=int, N=3 ke saath → value = 1 + Rank<int>::value.
  3. Rank<int> primary se match karta hai → 0.
  4. 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) int ke 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 wins2.

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.