title: How to get compiler to prefer const method overloading in C++?
body: <p>I've got a C++ member function of a class with a <code>const</code> and non-<code>const</code> overloading.</p>
  
  <pre><code>Class Example {
  public:
    int const &amp; Access() const;
    int       &amp; Access();
  
    [...]
  };
  </code></pre>
  
  <p>I wish for the const version to be preferred as the performance is way superior in my code, the non-const version causing a copy of the underlying shared object to be created to permit modification.</p>
  
  <p>Right now, if my caller has a non-const <code>Example</code> object, the non-const Access() method is used even if the resultant int is not modified.</p>
  
  <pre><code>Example example;
  
  if ( modify ) {
      example.Access() = 23;    // Need to perform expensive copy here.
  } else {
      cout &lt;&lt; example.Access(); // No need to copy, read-only access.
  }
  </code></pre>
  
  <p>Is there a way, such as distinguishing lvalue and rvalue uses of the return value, perhaps using perfect forwarding with templates, to create a similar mechanism in C++17 that permits the caller to have one syntax which the compiler only uses the non-const version if the return value is modified?</p>
  
  <p>Another example of where I need this is <code>operator -&gt; ()</code> where I have a <code>const</code> and non-<code>const</code> version of the operator.  When calling a method that is <code>const</code> I'd like the compiler to prefer the <code>const</code> version of <code>operator -&gt; ()</code>.</p>
  
  <pre><code>Class Shared {
    public:
      int Read() const;
      void Write(int value);
  
      [...]
  };
  
  template &lt;typename BaseClass&gt;
  class Callback {
  public:
    BaseClass const * operator -&gt; () const; // No tracking needed, read-only access.
    BaseClass       * operator -&gt; ();       // Track possible modification.
  
    [...]
  };
  
  typedef Callback&lt;Shared&gt; SharedHandle;
  
  Shared shared;
  SharedHandle sharedHandle(&amp;shared);
  
  if ( modify ) {
    sharedHandle-&gt;write(23);
  } else {
    cout &lt;&lt; sharedHandle-&gt;Read();
  }
  </code></pre>