§21.4.5 [string.access]
const_reference operator[](size_type pos) const;
reference operator[](size_type pos);
Returns:
*(begin() + pos)
ifpos < size()
. Otherwise, returns a reference to an object of typecharT
with valuecharT()
, where modifying the object leads to undefined behavior.
The second part implies, to me atleast, that this "object of type charT
" may reside outside of the sequence stored in the std::string
object. Example implementation of a conforming operator[]
:
reference operator[](size_type pos){
static contexpr charT default = charT();
if(pos == size())
return default;
return buf[pos];
}
Now, c_str()
/data()
, are specified in terms of operator[]
:
§21.4.7 [string.accessors]
const charT* c_str() const noexcept;
const charT* data() const noexcept;
Returns: A pointer
p
such thatp + i == &operator[](i)
for eachi
in[0,size()]
.
This would make the above operator[]
implementation non-conformant, as p + size() != &operator[](size())
. However, with a bit of trickery, you can circumvent this problem:
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;
}
Now, the obvious question is...
Is the above code really conformant or did I overlook something?
Ignoring the given code, considering only the question, I think that
Hence, it appears to be a defect.
Checking the list of known library defects apparently this issue has not yet been reported.
So, as I stated in chat, I recommend posting it to [comp.std.c++], in order to get resolved the question of whether it really is a defect, and if so, to get it into the defects list and fixed.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With