title: Why does double negation change the value of C++ concept?
body: <p>A friend of mine shown me a C++20 program with concepts, which puzzled me:</p>
  <pre><code>struct A { static constexpr bool a = true; };
  
  template &lt;typename T&gt;
  concept C = T::a || T::b;
  
  template &lt;typename T&gt;
  concept D = !!(T::a || T::b);
  
  static_assert( C&lt;A&gt; );
  static_assert( !D&lt;A&gt; );
  </code></pre>
  <p>It is accepted by all compilers: <a href="https://gcc.godbolt.org/z/e67qKoqce" rel="noreferrer">https://gcc.godbolt.org/z/e67qKoqce</a></p>
  <p>Here the concept <code>D</code> is the same as the concept <code>C</code>, the only difference is in double negation operator <code>!!</code>, which from the first sight shall not change the concept value. Still for the struct <code>A</code> the concept <code>C</code> is true and the concept <code>D</code> is false.</p>
  <p>Could you please explain why it is so?</p>