title: Constexpr member function
body: <p>Suppose I have a <code>struct</code> template <code>S</code> that is parametrized by an engine:</p>
  
  <pre><code>template&lt;class Engine&gt; struct S;
  </code></pre>
  
  <p>I have two engines: a "static" one with a <code>constexpr</code> member function <code>size()</code>, and a "dynamic" one with a non-<code>constexpr</code> member function <code>size()</code>:</p>
  
  <pre><code>struct Static_engine {
      static constexpr std::size_t size() {
          return 11;
      }
  };
  
  struct Dynamic_engine {
      std::size_t size() const {
          return size_;
      }
      std::size_t size_ = 22;
  };
  </code></pre>
  
  <p>I want to define <code>size()</code> member function in <code>S</code> that can be used as a <code>constexpr</code> if the engine's <code>size()</code> is <code>constexpr</code>. I write:</p>
  
  <pre><code>template&lt;class Engine&gt;
  struct S {
      constexpr std::size_t size() const {
          return engine_.size();
      }
      Engine engine_;
  };
  </code></pre>
  
  <p>Then the following code compiles with GCC, Clang, MSVC and ICC:</p>
  
  <pre><code>S&lt;Static_engine&gt; sta;         // not constexpr
  S&lt;Dynamic_engine&gt; dyn;
  
  constexpr auto size_sta = sta.size();
  const auto size_dyn = dyn.size();
  </code></pre>
  
  <p>Taking into account intricacies of <code>constexpr</code> and various "ill-formed, no diagnostic is required", I still have the question: is this code well-formed?</p>
  
  <p><a href="https://godbolt.org/z/EF_uGE" rel="noreferrer">Full code on Godbolt.org</a></p>
  
  <p>(I tagged this question with both <a href="/questions/tagged/c%2b%2b17" class="post-tag" title="show questions tagged &#39;c++17&#39;" rel="tag">c++17</a> and <a href="/questions/tagged/c%2b%2b20" class="post-tag" title="show questions tagged &#39;c++20&#39;" rel="tag">c++20</a> in case this code has different validity in these two standards.)</p>