§21.4.5 [string.access]
एक std :: स्ट्रिंग कार्यान्वयन अनुरूप है जहां 's.c_str() + s.size()' जरूरी नहीं है '& s [s.size()]'?
const_reference operator[](size_type pos) const;
reference operator[](size_type pos);
रिटर्न:
*(begin() + pos)
अगरpos < size()
। अन्यथा,charT
के प्रकारcharT()
के साथ किसी ऑब्जेक्ट का संदर्भ देता है, जहां ऑब्जेक्ट को संशोधित करने से अपरिभाषित व्यवहार होता है।
दूसरे भाग का तात्पर्य मुझे कम से कम करने के लिए, कि यह "प्रकार charT
की वस्तु" अनुक्रम std::string
वस्तु में संग्रहीत के बाहर रहते हैं हो सकता है। एक अनुरूप operator[]
का उदाहरण कार्यान्वयन:
reference operator[](size_type pos){
static contexpr charT default = charT();
if(pos == size())
return default;
return buf[pos];
}
अब, c_str()
/data()
, operator[]
के मामले में निर्दिष्ट कर रहे हैं:
§21.4.7 [string.accessors]
const charT* c_str() const noexcept;
const charT* data() const noexcept;
रिटर्न: एक संकेतक
p
ऐसा है कि प्रत्येकके लिएp + i == &operator[](i)
[0,size()]
में।
इससे ऊपर operator[]
कार्यान्वयन गैर-अनुरूप होगा, p + size() != &operator[](size())
के रूप में। हालांकि, प्रवंचना का एक सा के साथ, आप इस समस्या को दरकिनार कर सकते हैं:
reference operator[](size_type pos){
static contexpr charT default = charT();
if(pos == size() && !evil_context) // assume 'volatile bool evil_context;'
return default;
return buf[pos];
}
struct evil_context_guard{
volatile bool& ctx;
evil_context_guard(volatile bool& b)
: ctx(b) {}
~evil_context_guard(){ b = false; }
};
const charT* c_str() const noexcept{
evil_context_guard g(evil_context = true);
// now, during the call to 'c_str()', the requirement above holds
// 'p + i == &operator[](i) for each i in [0,size()]'
const charT* p = &buf[0];
assert(p+size() == &operator[](size()));
return p;
}
अब, स्पष्ट सवाल यह है कि ...
ऊपर कोड वास्तव में अनुरूप है या मैं कुछ को नजरअंदाज किया?
एक बात मुझे पता है कि यदि आप वास्तव में एक स्ट्रिंग ऑब्जेक्ट 'str' के लिए चेक आउट लिखते थे: 'char * p = str.c_str(); size_t i = str.size(); जोर दें (पी + i == और str [i]); 'आपके कोड के साथ दावा विफल हो जाएगा। मानक एक विशिष्ट संदर्भ निर्दिष्ट नहीं करता है जहां invariant को पकड़ना चाहिए, इसलिए मैं यह मानने के बारे में सावधान रहूंगा कि इसे केवल 'c_str() 'रिटर्न से पहले पकड़ना होगा। – pmdj