5.2.18 · D5 · HinglishC++ Programming

Question bankConcepts (C++20) — constraining templates

1,481 words7 min read↑ Read in English

5.2.18 · D5 · Coding › C++ Programming › Concepts (C++20) — constraining templates


True or false — justify

A concept runtime state rakh sakta hai jo calls ke beech change ho.
False. Ek concept ek ==constexpr bool template== hai jo poori tarah se compile time par apne type arguments se fix hota hai; iske paas koi storage nahi hai aur yeh kabhi runtime par execute nahi hota.
requires(T a){ a + a; } constraint check hone par actually a ko a mein add karta hai.
False. Braces sirf yeh test karte hain ki a + a ek well-formed expression hai ya nahi; kuch bhi compute nahi hota aur a ek kalpanit variable hai jo kabhi construct nahi hota.
Agar Numeric<T> false hai, to ise use karne wala template usi jagah compile error deta hai.
False. Constrained template ko candidate set se silently remove kar diya jaata hai; error tab aata hai jab koi bhi candidate survive nahi karta.
concept C = requires(T){ }; jisme empty body ho, hamesha true hota hai.
True. Ek empty requires-expression mein fail hone ke liye koi requirements nahi hain, isliye "har requirement satisfy hoti hai" ka conjunction kisi bhi T ke liye vacuously true hota hai.
std::integral<double> true hai.
False. double ek floating type hai; std::integral sirf integer types jaise int, long, char, bool se match karta hai — dekho type_traits — std::integral, std::floating_point.
Do overloads jinke identical constraints hain, jab dono match karein to ambiguous hote hain.
True. Subsumption tie tabhi todata hai jab ek constraint strictly stronger ho; equal constraints hone par compiler ke paas ek ko prefer karne ka koi tarika nahi hota, isliye woh ambiguity report karta hai.
SignedIntegral ka Integral ko subsume karna matlab SignedIntegral zyada types accept karta hai.
False. Yeh kam types accept karta hai (ek stricter set); "subsumes" ka matlab hai "strictly zyada require karta hai", isliye zyada-constrained overload preferred hota hai.
Ek requires-clause aur ek requires-expression ek hi keyword hai jo ek hi kaam karta hai.
False. Clause ek constraint introduce karta hai (requires Numeric<T>, ek bool evaluate karta hai); expression ek bool banata hai by listing testable expressions (requires(T a){ a+a; }).
Tum concept definition body ke andar if (...) { ... } rakh sakte ho.
False. Ek concept ki body ek single ==constexpr bool expression== honi chahiye; yeh ek predicate definition hai, koi statement block nahi.
requires requires hamesha ek typo hota hai.
False. Yeh legal hai: pehla requires clause hai, doosra ek inline requires-expression shuru karta hai — requires requires(T a){ a.size(); }.

Spot the error

template<Numeric> T sq(T x){...} — kya galat hai?
Constrained-parameter form ko ek naam chahiye: template<Numeric T>. Sirf Numeric likha ho to body mein use karne ke liye koi type name T nahi hai.
concept Even = (T % 2 == 0); — yeh ill-formed kyun hai?
Ek concept types par predicate hota hai, values par nahi; T ek type hai, isliye T % 2 meaningless hai. Concepts test karte hain ki ek type kaunse operations support karta hai, kabhi koi runtime value nahi.
requires(T a){ { a.size() } -> int; } — kya galti hai?
Compound requirement ka -> ek type-constraint (ek concept) naam karna chahiye, koi bare type nahi. Sahi: -> std::convertible_to<int>.
auto f(Numeric x){ return x*x; } — yeh x ko constrain kyun nahi karega?
Abbreviated form ko auto chahiye: Numeric auto x. auto ke bina, Numeric ko ek type name ki tarah padha jaata hai (aisa koi type exist nahi karta), isliye yeh intended se alag reason ke liye compile fail karta hai.
template<typename T> requires Numeric<T> && — trailing && — kya yeh theek hai?
Nahi, yeh ek syntax error hai: ek requires-clause ek complete constraint expression hona chahiye. Lekin dhyan do ki paas mein ek valid galti bhi hai — requires (A || B) && C ko parentheses chahiye kyunki subsumption ke liye constraints mein ||/&& ki specific grouping hoti hai.
concept C = std::integral<T> || std::floating_point; — dhundo.
std::floating_point mein argument <T> missing hai. Disjunction mein har atomic concept ko ek type par apply kiya jana chahiye.

Why questions

Constraints se errors call site par kyun point karti hain, template guts ke andar nahi?
Constraint pehle check hoti hai template body instantiate hone se, isliye compiler type ko use ke point par hi reject karta hai, na ki baad mein us code ke andar fail karke jo tumne kabhi likha hi nahi.
Inline requires requires ki jagah named concept kyun prefer karein?
Ek named concept reusable, self-documenting hota hai, aur subsumption mein participate karta hai (compiler named atomic constraints ko compare kar sakta hai); ad-hoc inline requires-expressions opaque hote hain aur ek-doosre ke against order nahi kiye ja sakte.
int ke liye std::integral vs std::floating_point par overloading kabhi clash kyun nahi karta?
int ke liye, floating_point<int> false hai, isliye woh overload candidates se poori tarah remove ho jaata hai — sirf ek survive karta hai, isliye disambiguate karne ke liye kuch hai hi nahi.
Concepts ne std::enable_if gymnastics ko largely replace kyun kiya?
Concepts readable call-site errors aur subsumption ke zariye automatic ordering dete hain, jabki SFINAE and std::enable_if intent ko return-type/parameter tricks mein chhupaata tha aur cryptic "no matching function" walls produce karta tha.
requires(T a, T b) mein variables kabhi actually construct kyun nahi hone chahiye?
Yeh sirf expression validity test karne ke liye kalpanit stand-ins hain; agar compiler inhe banata to use ek constructor ki zarurat hoti jo type mein ho hi na, jo sirf well-formedness check karne ke purpose ko hi defeat kar deta.
Compound requirement { e } -> C simple requirement e; se zyada strong kyun hai?
Simple form sirf yeh poochta hai ki e compile hoga ya nahi; compound form bhi concept C ke zariye ==e ke type== ko constrain karta hai, un cases ko pakad kar jahan expression valid ho lekin galat type return kare.

Edge cases

Addable<void> kya hoga jahan Addable = requires(T a,T b){ a+b; }?
false — tum void type ke parameters declare nahi kar sakte, isliye requires-expression ki parameter list ill-formed hai aur concept error karne ki jagah false yield karta hai.
Kya ek concept class ke bahar se requires(T a){ a.secret(); } test karte waqt private members dekhta hai?
Nahi. Access rules tab bhi apply hote hain; a.secret() well-formed nahi hai agar secret us context mein private hai, isliye requirement fail hoti hai jaise normal code mein hota.
Agar ek type dono Integral aur user concept PrintableInt ko satisfy karta hai jo Integral bhi require karta hai, to kaunsa overload jeeega?
PrintableInt, kyunki yeh Integral ki sabhi requirements plus aur bhi require karta hai — yeh Integral ko subsumes karta hai, isliye yeh zyada-constrained, preferred candidate hai.
Kya ek concept recursive ho sakta hai (khud ko refer kar sake)?
Nahi. Ek concept ki constraint apni khud ki satisfaction par depend kiye bina resolvable honi chahiye; self-reference ill-formed hai, ordinary recursive templates ke unlike.
Nested requires requires(decltype(*std::begin(r)) x){ std::cout << x; } kisse bachata hai?
Yeh check karta hai ki har element streamable hai, isliye ek vector<NoStreamType> call site par cleanly reject hota hai, range-for loop ke andar explode karne ki jagah — Ranges library (C++20) pattern.
Jab zero overloads constraint checking ke baad survive karein, tumhe kya message milta hai?
Woh clean "no matching function for call" — jo bilkul wahi desired outcome hai, kyunki har candidate ko ek stated, checkable reason ke liye silently remove kiya gaya tha.

Recall Ek-line self-test

"Constraint fails" ka matlab hai template remove hota hai, error nahi — aur errors tab surface hoti hain jab poora candidate set empty ho. Justify karo ki removal (error nahi) sahi design kyun hai. ::: Yahi concepts-based overloading ko kaam karta hai: har unsatisfied overload side mein hat jaata hai taaki sahi wala choose ho sake, jaise Overload Resolution & Subsumption candidates ko filter karta hai.