title: Comparison object being invocable as const
body: <p>When I try to run the following code, both clang (6.0) and g++ (8) with -std=c++17 give me a static_assert error:</p>
  
  <pre><code>#include &lt;set&gt;
  struct A {};
  
  struct ProcessComparator { inline bool operator()(const A&amp;, const A&amp;) { return true; } };
  
  int main(void)
  {
      std::set&lt;A, ProcessComparator&gt; A_Set;
  
      return EXIT_SUCCESS;
  }
  </code></pre>
  
  <p>g++ 8</p>
  
  <blockquote>
    <p>/usr/bin/../lib/gcc/x86_64-linux-gnu/8/../../../../include/c++/8/bits/stl_tree.h:457:7: error: static_assert failed due to requirement 'is_invocable_v' "comparison object must be invocable as const"</p>
  </blockquote>
  
  <p>clang 6.0</p>
  
  <blockquote>
    <p>/usr/include/c++/8/bits/stl_tree.h:457:21: error: static assertion failed: comparison object must be invocable as const</p>
  </blockquote>
  
  <p>Putting a const as part of the operator() signature fixes this problem:</p>
  
  <pre><code>#include &lt;set&gt;
  
  struct A {};
  
  /* Add const as part of the operator's signature */
  struct ProcessComparator { inline bool operator()(const A&amp;, const A&amp;) const { return true; } };
  
  int main(void)
  {
      std::set&lt;A, ProcessComparator&gt; A_Set;
  
      return EXIT_SUCCESS;
  }
  </code></pre>
  
  <p>Meanwhile with std=c++14 the error goes away in both clang and g++. </p>
  
  <p>My question is what changed in c++17 for this to now give an error and why does the const here matter? </p>
  
  <p>The const only guarantees that every object declared inside the ProcessComparator class doesn't get modified (aside from those with mutable), so why is this a requirement?</p>
  
  <hr/>
  
  <p>This is the source code from the source code where the static assert fails:</p>
  
  <pre><code>#if __cplusplus &gt;= 201103L
        static_assert(__is_invocable&lt;_Compare&amp;, const _Key&amp;, const _Key&amp;&gt;{},
        "comparison object must be invocable with two arguments of key type");
  # if __cplusplus &gt;= 201703L
        // _GLIBCXX_RESOLVE_LIB_DEFECTS
        // 2542. Missing const requirements for associative containers
        static_assert(is_invocable_v&lt;const _Compare&amp;, const _Key&amp;, const _Key&amp;&gt;,
        "comparison object must be invocable as const");
  # endif // C++17
  #endif // C++11
  </code></pre>
  
  <p>A new static_assert was added where the Comparison object was changed from just <code>_Compare&amp;&lt;</code> to <code>const _Compare&amp;</code> and <code>is_invocable</code> to <code>is_invocable_v</code>, although that, from what I can understand, is just to gain inline and constexpr <a href="https://en.cppreference.com/w/cpp/types/is_invocable" rel="noreferrer">as seen here</a></p>
  
  <hr/>
  
  <p>I've found <a href="https://cplusplus.github.io/LWG/issue2542" rel="noreferrer">this</a> link, based on the source code comment, but I still cannot understand <b>why</b> this is required.</p>