अंतिम अद्यतन:2026-10-12
C++17 optional_ref¶
यह लेख foonathan के ब्लॉग optional_ref discussion की विवेचना है; मूल लेख इस बात पर सबसे शानदार चर्चा है कि std::optional<T&> (optional संदर्भ) अंततः मानक में क्यों नहीं आया। C++26 की पूर्व-संध्या पर यह विषय फिर उठा, इसलिए मुख्य तर्कों को दोहराना लाभदायक है।
1. समस्या: std::optional compile क्यों नहीं होता?¶
std::optional<int>, std::optional<std::string> दोनों ठीक हैं, लेकिन std::optional<int&> सीधे compile error देता है। कारण थोड़ा "ऐतिहासिक विरासत" जैसा है: मानक बनाते समय इसकी assignment semantics पर सहमति नहीं बनी, तो मानक में सीधे लिख दिया गया कि T संदर्भ प्रकार होने पर व्यवहार undefined है।
तो एक "संभवतः खाली संदर्भ" में आख़िर कठिन क्या है? लेखक ने चार प्रश्न निचोड़े:
(1) क्या optional<T&> और pointer एक ही चीज़ हैं?
(2) क्या हमें सचमुच optional<T&> चाहिए?
(3) assign करते समय rebind (नए object से फिर बंधना) चाहिए या assign-through (इंगित object में लिखना)?
(4) इसमें assignment operator होना ही चाहिए या नहीं?
लेखक के tl;dr उत्तर: नहीं, नहीं चाहिए, rebind, नहीं होना चाहिए। अब देखें क्यों।
2. optional संदर्भ pointer नहीं है¶
सहज रूप से "संभवतः खाली संदर्भ" pointer ही है, लेकिन लेखक ने एक और बुनियादी अंतर बताया:
T&का निर्माण और पहुँच दोनों implicit हैं: संदर्भ मिलते ही सीधे इस्तेमाल करें, dereference की ज़रूरत नहीं;T*का निर्माण और पहुँच दोनों explicit हैं:&xसे पता लेना पड़ता है,*pसे dereference करना पड़ता है।
यह explicitness का अंतर मूल्यवान है: pointer आपको याद दिलाता है कि "यहाँ null हो सकता है, aliasing की समस्या हो सकती है"। optional<T&> को हर जगह implicit conversion वाला "अधिक सुविधाजनक pointer" बना देना ठीक इसी सुरक्षा-परत को फेंक देना है। लेखक का निष्कर्ष: अगर आपको "संभवतः खाली" व्यक्त करना है, तो explicit T* बेहतर documentation है।
3. rebind या assign-through¶
यह पूरी चर्चा का केंद्रीय अवरोध है:
दो व्याख्याएँ:
- rebind: opt अब b से बंध गया (संदर्भ की alias semantics;
int& ra = a; ra = b;b को a में assign करता है…… रुकिए,int&का assignment तो ठीक assign-through ही है!) - assign-through: b का मान a में लिखना (सामान्य संदर्भ
T&की semantics)।
विरोधाभास यहीं है: अगर optional संदर्भ T& की semantics से मेल खाना चाहे तो assignment, assign-through होना चाहिए; लेकिन एक mutable optional (जिसमें दूसरा object भी भरा जा सके) सहज रूप से rebind माँगता है। दोनों semantics तर्कसंगत हैं, समिति कोई निष्कर्ष नहीं निकाल पाई, और इस तरह optional<T&> कभी वैध नहीं हुआ।
व्यवहार में rebind semantics चाहिए तो समुदाय का समाधान है अपना optional_ref<T> बनाना: भीतर T* रखते हैं, assignment में सिर्फ pointer बदलते हैं—— semantics बिल्कुल साफ। C++26 का std::optional_ref प्रस्ताव भी यही रास्ता लेता है।
4. सारांश¶
(1) optional<T&> pointer का syntactic sugar नहीं है; दोनों की explicitness में बुनियादी भूमिका-विभाजन है;
(2) इसे रोकने वाली चीज़ assignment semantics की द्विअर्थकता है: rebind और assign-through दोनों तर्कसंगत लगते हैं;
(3) "शून्य-संभावित संदर्भ" चाहिए तो explicit pointer या optional_ref, "वैध किया गया optional
अंत में एक प्रश्न: optional<T&> का value() और *opt, T& लौटाए या const T&? और अगर const के रूप में capture की semantics भी व्यक्त करनी हो तो template parameter का डिज़ाइन कैसा हो?
संबंधित विषय¶
- C++17 [[nodiscard]] एट्रिब्यूट | C++那些事
- C++17 std::string_view | C++那些事
- C++17 PMR मेमोरी रिसोर्सेज़ | C++那些事
- C++17 सत्तरह उन्नत विशेषताएँ | C++那些事
- C++17 क्लास टेम्प्लेट आर्ग्युमेंट डिडक्शन CTAD | C++那些事
- C++17 std::variant | C++那些事
- C++17 स्ट्रक्चर्ड बाइंडिंग्स | C++那些事
- C++17 टेम्प्लेट auto डिडक्शन | C++那些事
- C++17 वेरिएबल टेम्प्लेट्स | C++那些事