title: const vs non-const of container and its content
body: <p>With a container class, such as <code>std::vector</code>, there are two different concepts of constant-ness: that of the container (i.e. its size) and that of the elements. It seems that <code>std::vector</code> confuses these two, such that the following simple code won't compile:</p>
  
  <pre><code>struct A {
    A(size_t n) : X(n) {}
    int&amp;x(int i) const { return X[i]; }    // error: X[i] is non-const.
  private:
    std::vector&lt;int&gt; X;
  };
  </code></pre>
  
  <p>Note that even though the <em>data members</em> (the three pointers to the begin&amp;end of the data and the end of the allocated buffer) of <code>std::vector</code> are <strong>not</strong> changed by a call to its <code>operator[]</code>, this member is not <code>const</code> -- isn't this a strange design?</p>
  
  <p>Note also that for raw pointers, these two concepts of constant-ness are neatly separated, such that the corresponding raw-pointer code</p>
  
  <pre><code>struct B {
    B(size_t n) : X(new int[n]) {}
    ~B() { delete[] X; }
    void resize(size_t n);                 // non-const
    int&amp;x(int i) const { return X[i]; }    // fine
  private:
    int*X;
  };
  </code></pre>
  
  <p>works just fine.</p>
  
  <p>So what is the correct/recommended way to deal with this when using <code>std::vector</code> (without using <code>mutable</code>)?</p>
  
  <p>Is a <code>const_cast&lt;&gt;</code> as in</p>
  
  <pre><code>int&amp;A::x(int i) const { return const_cast&lt;std::vector&lt;int&gt;&amp;&gt;(X)[i]; }
  </code></pre>
  
  <p>deemed acceptable (<code>X</code> is known to be non-<code>const</code>, so no UB here)?</p>
  
  <p><strong>EDIT</strong> just to prevent further confusion: I do want to modify the elements, i.e. the <em>contents of the container but not the container itself</em> (the size and/or memory location).</p>