title: Propagate constness to data pointed by member variables
body: <p>It is often quite confusing to C++ newcomers that const member functions are allowed to call non-const methods on objects referenced by the class (either by pointer or reference). For example, the following is perfectly correct:</p>
  
  <pre><code>class SomeClass
  {
      class SomeClassImpl;
      SomeClassImpl * impl_; // PImpl idiom
  
    public:    
  
      void const_method() const;
  };
  
  struct SomeClass::SomeClassImpl
  {
      void non_const_method() { /*modify data*/ }
  };
  
  void SomeClass::const_method() const
  {
      impl_-&gt;non_const_method(); //ok because impl_ is const, not *impl_
  };
  </code></pre>
  
  <p>However, it would sometimes be rather handy if the constness would propagate to pointed objects (I voluntarily used the PImpl idiom because it is one of the case where I think "constness propagation" would be very useful).</p>
  
  <p>When using pointers, this can easily be achieved by using some kind of smart pointer with operators overloaded on constness:</p>
  
  <pre><code>template &lt; typename T &gt;
  class const_propagating_ptr
  {
    public:
  
      const_propagating_ptr( T * ptr ) : ptr_( ptr ) {}
  
      T       &amp; operator*()       { return *ptr_; }
      T const &amp; operator*() const { return *ptr_; }
  
      T       * operator-&gt;()       { return ptr_; }
      T const * operator-&gt;() const { return ptr_; }
  
      // assignment operator (?), get() method (?), reset() method (?)
      // ...
  
    private:
  
      T * ptr_;
  };
  </code></pre>
  
  <p>Now, I just need to modify <code>SomeClass::impl_</code> to be a <code>const_propagating_ptr&lt;SomeClassImpl&gt;</code> to obtain the wanted behavior.</p>
  
  <p>So I have a few questions about this:</p>
  
  <ol>
  <li>Are there some issues with constness propagation that I have overlooked?</li>
  <li>If not, are there any libraries that provide classes to obtain constness propagation?</li>
  <li>Wouldn't it be useful that the common smart pointers (unique_ptr, shared_ptr, etc.) provide some mean to obtain this behavior (for example through a template parameter)?</li>
  </ol>