title: Taking the address of a function and discarding it at compile time: is this valid C++?
body: <p>I was looking for a way to restrict template type parameters to those implementing functions of given signature. I seem to have arrived at quite elegant solution that allows for self-documenting code and rather clean, Concept-like error messages. The only problem is that I'm not sure if that's valid C++ or something that just happens to work in clang and gcc.</p>
  
  <p>Here's the code:</p>
  
  <pre><code>#include &lt;type_traits&gt;
  using std::enable_if;
  
  // let's say we want something with a "regular" operator+
  
  class Thing
  {
  public:
      Thing operator+(const Thing&amp;){return Thing();} //the kind of operator we want
  };
  
  class OtherThing
  {
  public:
      OtherThing operator+(int){return OtherThing();} // the kind of operator we don't want
  };
  
  class YetAnotherThing
  {
      // no operator whatsoever
  };
  
  // The questionable line. I'm taking the address of the function and 
  // immediately discarding it using the comma operator.
  #define HAS_FUNCTION(type, ret, name, args...) (static_cast&lt;ret (type::*)(args)&gt;(&amp;type::name), 1)
  
  #define T_HAS_OPERATOR_PLUS HAS_FUNCTION(T, T, operator+, const T&amp;)
  
  template &lt;typename T&gt;
  typename enable_if&lt;T_HAS_OPERATOR_PLUS&gt;::type foo(T)
  {
      T t1, t2;
      t1 + t2;
  }
  
  #undef T_HAS_OPERATOR_PLUS
  
  int main()
  {
      Thing t;
      OtherThing ot;
      YetAnotherThing yat;
      foo(t);
      foo(ot);
      foo(yat);
  }
  </code></pre>
  
  <p>When build with clang it produces the following output:</p>
  
  <pre><code>main.cpp:43:2: error: no matching function for call to 'foo'
          foo(ot);
          ^~~
  main.cpp:29:47: note: candidate template ignored: substitution failure [with T = OtherThing]: static_cast from 'OtherThing (OtherThing::*)(int)' to 'OtherThing (OtherThing::*)(const OtherThing &amp;)' is not allowed
  typename enable_if&lt;T_HAS_OPERATOR_PLUS&gt;::type foo(T)
                     ~~~~~~~~~~~~~~~~~~~        ^
  main.cpp:44:2: error: no matching function for call to 'foo'
          foo(yat);
          ^~~
  main.cpp:29:47: note: candidate template ignored: substitution failure [with T = YetAnotherThing]: no member named 'operator+' in 'YetAnotherThing'
  typename enable_if&lt;T_HAS_OPERATOR_PLUS&gt;::type foo(T)
                     ~~~~~~~~~~~~~~~~~~~        ^
  2 errors generated.
  </code></pre>
  
  <p>...which looks pretty nice compared to the usual arcane blizzard.</p>
  
  <p>So, my question is: is it valid in standard C++14? After all I am taking an address at compile time, it seems like something that would be disallowed by the standard.</p>
  
  <p>Also, since I'm but a mere apprentice of the dark arts, perhaps there's a more straightforward way to accomplish this? </p>
  
  <p>Either way any input is welcome. Thanks in advance.</p>