title: Why C++ pretends to forget previously parsed templates?
body: <p>Here is data serialization program which compiles with <code>gcc 11.1</code>:</p>
  <pre><code>#include &lt;fstream&gt;
  #include &lt;ranges&gt;
  #include &lt;concepts&gt;
  #include &lt;map&gt;
  using namespace std;
  
  void write( fstream &amp; f, const integral auto &amp; data ) {
      f.write( (const char*)&amp;data, sizeof( data ) );
  }
  
  void write( fstream &amp; f, const pair&lt;auto,auto&gt; &amp; p ) {
      write( f, p.first );
      write( f, p.second );
  }
  
  template&lt; ranges::range T &gt;
  void write( fstream &amp; f, const T &amp; data ) {
      const uint64_t size = ranges::size( data );
      write( f, size );
      for ( const auto &amp; i : data )
          write( f, i );
  }
  
  int main() {
      auto f = fstream( &quot;spagetti&quot;, ios::out | ios::binary );
      const bool pls_compile = true;
      if constexpr (pls_compile) {
          write( f, pair&lt; int, int &gt;( 123, 777 ) );
          write( f, map&lt; int, int &gt;{ { 1, 99 }, { 2, 98 } } );
      }
      else
          write( f, pair&lt; map&lt; int, int &gt;, int &gt;( { { 1, 99 }, { 2, 98 } }, 777 ) );
  }
  </code></pre>
  <p>which made me a happy developer of serialization <em>library</em> which provides functions to serialize to file anything that is <code>integral || pair || range</code>. But it turned out that if you set <code>pls_compile = false</code>, then compilation fails with <code>spagetti.cpp:12:10: error: no matching function for call to 'write(std::fstream&amp;, const std::map&lt;int, int&gt;&amp;)'</code>. It can't be fixed by moving declaration of <code>write( pair )</code> past <code>write( range )</code> because <code>pls_compile = true</code> will stop compiling then.</p>
  <p>What is the best way to fix it and why compiler <em>forgets</em> about existence of <code>write( range )</code> while generating implementation of <code>write( pair&lt; map, int &gt; )</code> based on <code>write( pair )</code> template? It clearly should be already familiar with <code>write( range )</code> since it already proceeded down to <code>write( pair&lt; map, int &gt; )</code>.</p>