title: How to detect if a class has a templated member function?
body: <h5>I know some codes that can detect if a class has a member function, like below</h5>
  <pre><code>#include &lt;iostream&gt;
  #include &lt;type_traits&gt;
  #include &lt;string&gt;
  
  using namespace std;
  
  template&lt;typename T, typename F&gt;
  constexpr auto has_member_impl(F&amp;&amp; f) -&gt; decltype(f(std::declval&lt;T&gt;()), true) { return true; }
  template&lt;typename&gt;
  constexpr bool has_member_impl(...) { return false; }
  #define has_member(T, EXPR) has_member_impl&lt;T&gt;( [](auto&amp;&amp; obj)-&gt;decltype(obj.EXPR){} )
  
  class A{
  public:
    void operator()(int data){ cout &lt;&lt; data &lt;&lt; endl; }
  };
  
  class B{
  public:
    template &lt;class CLASS&gt;
    void func_int(CLASS &amp;c, int data){ 
      if constexpr(has_member(CLASS, operator()(int()))) c(data);
    }
    template &lt;class CLASS&gt;
    void func_string(CLASS &amp;c, std::string data){
      if constexpr(has_member(CLASS, operator()(std::string()))) c(data);
    }
  };
  
  int main(){
    A a;
    B b;
    b.func_int(a, 1); // print out 1
    b.func_string(a, &quot;2&quot;); // print out nothing, unless class 'A' defines 'operator()(string);'
  }
  </code></pre>
  <p>where,</p>
  <ul>
  <li>class A holds a member function 'operator()'</li>
  <li>in class B, functions 'func_int' and 'func_string' use constexpr(has_member(...)) to detect if 'operator()(int)' and 'operator()(std::string)' exist in a CLASS, respectively. If yes, execute that function.</li>
  </ul>
  <h5>When the member function of class A is a template function, the code can be something like below,</h5>
  <pre><code>class A{
  public:
    template &lt;typename T&gt;
    void operator()(T data){ cout &lt;&lt; data &lt;&lt; endl; }
  };
  
  class B{
  public:
    template &lt;class CLASS, typename DATA&gt;
    void func(CLASS &amp;c, DATA data){
      if constexpr(has_member(CLASS, operator()(1))) c(data);
    }
  };
  
  int main(){
    A a;
    B b;
    b.func(a, 1); // print out 1
    b.func(a, &quot;2&quot;); // print out 2
  }
  </code></pre>
  <p>where, the part of constexpr statement is changed to 'operator()(1)'</p>
  <h5>This time I want to make it more complex, like below</h5>
  <pre><code>class A{
  public:
    template &lt;typename T&gt;
    void operator()(T data1, T data2){ cout &lt;&lt; data1 &lt;&lt; ' ' &lt;&lt; data2 &lt;&lt; endl; }
  };
  
  class B{
  public:
    template &lt;class CLASS, typename DATA&gt;
    void func(CLASS &amp;c, DATA data1, DATA data2){
      if constexpr(has_member(CLASS, operator()(1, 2))) c(data1, data2);
    }
  };
  
  int main(){
    A a;
    B b;
    b.func(a, 1, 2); // print out '1 2'
    b.func(a, 1, &quot;2&quot;); // print out '1 2' (I want to make it print out nothing)
  }
  </code></pre>
  <p>where,</p>
  <ul>
  <li>in class A, the function 'operator()' accepts two parameters of the <strong>same type</strong></li>
  <li>it seems that the constexpr statament in class B can use any argument 'operator()(x,y)' to detect its existence, no matter whether the two parameters are of the same type</li>
  </ul>
  <p>What I want to know is that '<strong>when the function of A is a template function, how to detect if the two parameters are of the same type?</strong>'</p>