title: Uniformly calling -> or . in templated code with C++20 concepts
body: <p>In template code I want to detect if something is a pointer(this includes smart pointers like <code>std::unique_ptr</code>/<code>std::shared_ptr</code>) or value and then call <code>-&gt;some_func()</code> or <code>.some_func()</code>.</p>
  <p>I know the name of <code>some_func</code>, but sometimes people pass me pointers, sometimes they pass me values(and this is a fixed requirement, long story, but I can not just ask people to use <code>*</code> at callsite).</p>
  <p>So this is what I came up with.</p>
  <pre><code>#include &lt;iostream&gt;
  #include &lt;optional&gt;
  #include &lt;memory&gt;
  
  template&lt;typename T&gt; 
  auto&amp; get_dotable(T&amp; t){
      if constexpr (requires{*t;}) {
          return *t;
      } else{ 
          return t;
      }
  };
  
  void fn()
  {
      auto sps=std::make_shared&lt;std::string&gt;(&quot;abc&quot;);
      auto csps=std::make_shared&lt;const std::string&gt;(&quot;abc&quot;);
      auto ups=std::make_unique&lt;std::string&gt;(&quot;abc&quot;);
      auto os=std::optional&lt;std::string&gt;(&quot;abc&quot;);
      std::cout &lt;&lt; get_dotable(sps).size() &lt;&lt; std::endl;
      std::cout &lt;&lt; get_dotable(csps).size() &lt;&lt; std::endl;
      std::cout &lt;&lt; get_dotable(ups).size() &lt;&lt; std::endl;
      std::cout &lt;&lt; get_dotable(os).size() &lt;&lt; std::endl;
  }
  
  int main() {
      fn();
  }
  </code></pre>
  <p>I am fine with it blindly calling <code>*</code> on <code>std::optional</code> without checking if optional is engaged.</p>
  <p>It does not work with temporaries, but I am fine with that since I fear lifetime issues, although it prevents some nice usecases like:</p>
  <pre><code>std::cout &lt;&lt; get_dotable(ups.get()).size() &lt;&lt; std::endl;
  </code></pre>
  <p>Apart from these issues that I'm fine with, is there some problem with this solution, and is there a better way to do it instead?</p>