title: Can C++20 concepts be redeclared or not?
body: <p>This one's rather straightforward: according to the <a href="https://en.cppreference.com/w/cpp/language/constraints" rel="nofollow noreferrer">cppreference article</a>, concepts can be redeclared no problem:</p>
  <p><a href="https://i.stack.imgur.com/nQevB.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/nQevB.png" alt="image of cppreference saying it can be redeclared" /></a></p>
  <p>So I figured alright, cool, I don't have to worry about redeclaring my concept for creating &quot;printable enums&quot;; I can declare the concept in both my logging header and my common types header, so I only have to include what's needed:</p>
  <pre class="lang-cpp prettyprint-override"><code>// common types header
  #include &lt;enum_traits.hpp&gt;
  
  template&lt;typename E&gt;
  concept PrintableEnum = requires(E&amp; e) { {enum_traits&lt;E&gt;::toString(e)} -&gt; std::same_as&lt;const char*&gt;; };
  
  template&lt;PrintableEnum T&gt;
  std::ostream&amp; operator&lt;&lt;(std::ostream&amp; os, const T&amp; o)
  {
     os &lt;&lt; enum_traits&lt;T&gt;::toString(o);
     return os;
  }
  
  // logging header
  
  template&lt;typename T&gt;
  concept PrintableEnum = requires(T&amp; e) { {enum_traits&lt;T&gt;::toString(e)} -&gt; std::same_as&lt;const char*&gt;; };
  
  template&lt;PrintableEnum T&gt;
  plog::Record&amp; operator&lt;&lt;(plog::Record&amp; rec, const T&amp; o) 
  {
     rec &lt;&lt; enum_traits&lt;T&gt;::toString(o);
     return rec;
  }
  </code></pre>
  <p>(Ignore that the ostream overload could probably cover the plog record overload for the moment; that's probably how I'm gonna work around the problem, but I'm curious about this first.)</p>
  <p>So when I try to compile this, MSVC throws a fit for every file both headers are included in (which one it points to as the error changes based on include order):</p>
  <pre class="lang-sh prettyprint-override"><code>[build] commontypes.hpp(25): error C7571: 'PrintableEnum': variable template has already been initialized
  [build] logging.hpp(162): note: see declaration of 'PrintableEnum'
  </code></pre>
  <p>Also note, doing what cppreference does in that screenshot and duplicating the PrintableEnum declaration right under the first one in one of the files is the same problem.</p>
  <p>So, is cppreference <em>wrong</em> here? Does the standard not actually say anything about redeclarations? (I'm not actually sure where the official c++ standard is kept if not on cppreference...) Do I need to worry about redefinitions of concepts like anything else in C++?</p>
  <p>Or is MSVC wrong here? (Not that I can do much about MSVC...) Searching the error message only got me stuff about other redeclarations, like classes and variables. Apparently &quot;concept&quot; is not very SEO-friendly.</p>