title: Fixing third party code: "error: ‘enable_if’ in namespace ‘std’ does not name a template type"
body: <p>While trying to build a third party application, I found that one of its dependencies (<a href="https://github.com/genome/joinx" rel="nofollow noreferrer">https://github.com/genome/joinx</a>) would not compile cleanly with newer compilers. In the process of tidying it up (the code looks unmaintained since years), I got stuck with a compiler error I can't quite figure out.</p>
  
  <p>The issue is in this file:</p>
  
  <pre class="lang-cpp prettyprint-override"><code>
  #pragma once
  
  // Utilities for comparing things / establishing orderings.
  
  #include &lt;boost/utility/declval.hpp&gt;
  
  ///////////////////////////////////////////////////////////////////////////
  // Tags for use with enable_if
  
  // Compare objects return an int &lt;0, =0, or &gt;0 to establish an ordering
  // (cf. strcmp)
  struct CompareBase {};
  // ComparePred objects are predicates (e.g., less than)
  // (cf. std::less)
  struct ComparePredBase {};
  
  template&lt;typename Op&gt;
  struct DerefBinaryOp {
      Op op;
  
      explicit DerefBinaryOp(Op op = Op())
          : op(op)
      {}
  
      template&lt;typename ValueType&gt;
      auto operator()(ValueType const&amp; x, ValueType const&amp; y) -&gt; decltype(op(*x, *y)) {
          return op(*x, *y);
      }
  };
  
  // Given a "Compare" function, convert it to a less than predicate.
  template&lt;
            typename T
          , typename = typename std::enable_if&lt;std::is_base_of&lt;CompareBase, T&gt;::value&gt;::type
          &gt;
  struct CompareToLessThan : ComparePredBase {
      CompareToLessThan(T cmp = T())
          : cmp(cmp)
      {}
  
      template&lt;typename U&gt;
      bool operator()(U const&amp; x, U const&amp; y) const {
          return cmp(x, y) &lt; 0;
      }
  
      T cmp;
  };
  
  // Given a "Compare" function, convert it to a greater than predicate.
  template&lt;
            typename T
          , typename = typename std::enable_if&lt;std::is_base_of&lt;CompareBase, T&gt;::value&gt;::type
          &gt;
  struct CompareToGreaterThan : ComparePredBase {
      CompareToGreaterThan(T cmp = T())
          : cmp(cmp)
      {}
  
      template&lt;typename U&gt;
      bool operator()(U const&amp; x, U const&amp; y) const {
          return cmp(x, y) &gt; 0;
      }
  
      T cmp;
  };
  
  // This is a helper class that defines relational operators
  // (&gt;, &lt;, ==, !=, ...) for simple structs that define value_type
  // and have a single member: value_type value;
  template&lt;typename T&gt;
  struct ValueBasedRelOps {
      friend bool operator&lt;(T const&amp; lhs, T const&amp; rhs) {
          return lhs.value &lt; rhs.value;
      }
  
      friend bool operator&gt;(T const&amp; lhs, T const&amp; rhs) {
          return lhs.value &gt; rhs.value;
      }
  
      friend bool operator&lt;=(T const&amp; lhs, T const&amp; rhs) {
          return lhs.value &lt;= rhs.value;
      }
  
      friend bool operator&gt;=(T const&amp; lhs, T const&amp; rhs) {
          return lhs.value &gt;= rhs.value;
      }
  
      friend bool operator==(T const&amp; lhs, T const&amp; rhs) {
          return lhs.value == rhs.value;
      }
  
      friend bool operator!=(T const&amp; lhs, T const&amp; rhs) {
          return lhs.value != rhs.value;
      }
  };
  </code></pre>
  
  <p>And my compiler spews out errors:</p>
  
  <pre><code>/home/einar/Download/Sources/joinx/src/lib/common/RelOps.hpp:34:36: error: ‘enable_if’ in namespace ‘std’ does not name a template type
     34 |         , typename = typename std::enable_if&lt;std::is_base_of&lt;CompareBase, T&gt;::value&gt;::type
        |                                    ^~~~~~~~~
  /home/einar/Download/Sources/joinx/src/lib/common/RelOps.hpp:34:45: error: expected ‘&gt;’ before ‘&lt;’ token
     34 |         , typename = typename std::enable_if&lt;std::is_base_of&lt;CompareBase, T&gt;::value&gt;::type
        |                                             ^
  /home/einar/Download/Sources/joinx/src/lib/common/RelOps.hpp:52:36: error: ‘enable_if’ in namespace ‘std’ does not name a template type
     52 |         , typename = typename std::enable_if&lt;std::is_base_of&lt;CompareBase, T&gt;::value&gt;::type
        |                                    ^~~~~~~~~
  /home/einar/Download/Sources/joinx/src/lib/common/RelOps.hpp:52:45: error: expected ‘&gt;’ before ‘&lt;’ token
     52 |         , typename = typename std::enable_if&lt;std::is_base_of&lt;CompareBase, T&gt;::value&gt;::type
        |                                             ^
  </code></pre>
  
  <p>I'm unfamiliar with <code>std::enable_if</code> and the previous searches on SO did not yield a solution similar to my problem. What's the exact cause of the error, so I can start working from there to fix it?</p>