title: How can I use SFINAE to prioritise a non-templated function while also providing a return type?
body: <p><em>EDIT</em>: With apologies for the bad code before. Here is a compilable example that demonstrates the problem</p>
  
  <p>I'm trying to implement a visitor that simplifies to this basic pattern:</p>
  
  <pre><code>class Base {};
  
  class BaseA : public Base {};
  class BaseB : public Base {};
  
  class DerivedA : public BaseA {
  public:
      int operator+(DerivedA const&amp; a) const
      {
          return 10;
      }
  };
  
  class DerivedB : public BaseB {
  public:
      int operator+(DerivedB const&amp; b) const
      {
          return 10;
      }
  };
  
  struct Adder
  {
      int operator()(BaseA const&amp; a, BaseB const&amp; b)
      {
          std::cout &lt;&lt; "Addition is not supported for these types.";
          return -1;
      }
  
      template &lt;typename T, typename U&gt;
      int operator()(T const&amp; a, U const&amp; b)
      {
          return a + b;
      }
  };
  
  int main()
  {
      DerivedA a;
      DerivedB b;
      Adder adder;
      adder(a, a);
      adder(b, b);
      adder(a, b); // Compiler chooses templated function and fails if 
                   // operator+ is not supported.
  }
  </code></pre>
  
  <p>Where the base types match (which I have set up to be cases where <code>operator+</code> is not supported), I would like the compiler to choose the non-templated function. However, it is not.</p>
  
  <p>I believe I know why (direct template match is better than base class match), and the solution to <a href="https://stackoverflow.com/q/8594326/794283">Why is the compiler choosing this template function over an overloaded non-template function?</a> involving Substition Failure Is Not An Error (SFINAE) and <code>std::enable_if</code> seems very close.</p>
  
  <p>However, that solution only seems to be applicable to functions that return <code>void</code>. How can I adapt that SFINAE approach to allow me to provide a return type?</p>
  
  <p>See <a href="http://ideone.com/uEbVmU" rel="nofollow noreferrer">http://ideone.com/uEbVmU</a> for the compilation errors:</p>
  
  <pre><code>Compilation error    time: 0 memory: 3296 signal:0
  prog.cpp: In instantiation of ‘int Adder::operator()(const T&amp;, const U&amp;) [with T = DerivedA; U = DerivedB]’:
  prog.cpp:48:15:   required from here
  prog.cpp:37:22: error: no match for ‘operator+’ (operand types are ‘const DerivedA’ and ‘const DerivedB’)
               return a + b;
                        ^
  prog.cpp:37:22: note: candidate is:
  prog.cpp:12:13: note: int DerivedA::operator+(const DerivedA&amp;) const
           int operator+(DerivedA const&amp; a) const
               ^
  </code></pre>