In C++11 and beyond does std::string::operator[] do bounds checking?
<p>I have seen many times that <code>std::string::operator[]</code> does not do any bounds checking.  Even <a href="https://stackoverflow.com/questions/14699060/in-c-what-is-the-difference-between-stringat-and-stringoperator">What is the difference between string::at and string::operator[]?</a>, asked in 2013, the answers say that <code>operator[]</code> does not do any bounds checking.</p>

<p>My issue with this is if I look at the standard (in this case <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3797.pdf" rel="nofollow noreferrer">draft N3797</a>) in [string.access] we have </p>

<blockquote>
<pre><code>const_reference operator[](size_type pos) const;
reference operator[](size_type pos);
</code></pre>
  
  <ol>
  <li><em>Requires:</em> <code>pos &lt;= size()</code>.</li>
  <li><em>Returns:</em> <code>*(begin() + pos)</code> if <code>pos &lt; size()</code>. Otherwise, returns a reference to an object of type <code>charT</code> with value <code>charT()</code>, where modifying the object leads to undefined behavior.</li>
  <li><em>Throws:</em> Nothing.</li>
  <li><em>Complexity:</em> constant time.</li>
  </ol>
</blockquote>

<p>This leads me to believe that <code>operator[]</code> has to do some sort of bounds checking to determine if it needs to return a element of the string or a default <code>charT</code>.  Is this assumption correct and <code>operator[]</code> is now required to do bounds checking?</p>