title: enum and static const member variable usage in template trait class
body: <p>I want to test whether a class is streamable to <code>ostream&amp;</code> by seeing whether an overload for <code>operator&lt;&lt;</code> is provided. Based on <a href="https://stackoverflow.com/questions/6534041/how-to-check-whether-operator-exists">these</a> <a href="https://stackoverflow.com/questions/5768511/using-sfinae-to-check-for-global-operator">posts</a>, I tried to write another version using C++11. This is my attempt:</p>
  
  <pre><code>#include &lt;iostream&gt;
  #include &lt;type_traits&gt;
  
  namespace TEST{
    class NotDefined{};
  
    template&lt;typename T&gt; 
    NotDefined&amp; operator &lt;&lt; (::std::ostream&amp;, const T&amp;);
  
    template &lt;typename T&gt;
    struct StreamInsertionExists {
      static std::ostream &amp;s;
      static T const &amp;t;
      enum { value = std::is_same&lt;decltype(s &lt;&lt; t), NotDefined&gt;() };
    };
  }
  
  struct A{
    int val;
      friend ::std::ostream&amp; operator&lt;&lt;(::std::ostream&amp;, const A&amp;);
  };
  
  ::std::ostream&amp; operator&lt;&lt;(::std::ostream&amp; os, const A&amp; a)
  {
    os &lt;&lt; a.val;
    return os;
  }
  
  struct B{};
  
  int main() {
    std::cout &lt;&lt; TEST::StreamInsertionExists&lt;A&gt;::value &lt;&lt; std::endl;
    std::cout &lt;&lt; TEST::StreamInsertionExists&lt;B&gt;::value &lt;&lt; std::endl;
  
  }
  </code></pre>
  
  <p>But this fails to compile:</p>
  
  <blockquote>
  <pre><code>test_oper.cpp:40:57: error: reference to overloaded function could not be resolved; did you mean to call it?  
    std::cout &lt;&lt; TEST::StreamInsertionExists&lt;A&gt;::value &lt;&lt; std::endl;  
  
  /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/ostream:1020:1: note:  
    possible target for call  
      endl(basic_ostream&lt;_CharT, _Traits&gt;&amp; __os)  
  
  test_oper.cpp:30:17: note: candidate function not viable: no known conversion from 'TEST::NotDefined' to '::std::ostream &amp;'  
    (aka 'basic_ostream&lt;char&gt; &amp;') for 1st argument  
  ::std::ostream&amp; operator&lt;&lt;(::std::ostream&amp; os, const A&amp; a)  
  
  test_oper.cpp:15:15: note: candidate template ignored: couldn't infer template argument 'T'  
    NotDefined&amp; operator &lt;&lt; (::std::ostream&amp;, const T&amp;);  
  </code></pre>
  </blockquote>
  
  <p>However, if I replace the line<br>
  <code>enum { value = std::is_same&lt;decltype(s &lt;&lt; t), NotDefined&gt;() };</code><br>
  with<br>
  <code>static const bool value = std::is_same&lt;decltype(s &lt;&lt; t), NotDefined&gt;();</code><br>
  then everything compiles.  </p>
  
  <p>Why is there such a difference between the <code>enum</code> and the <code>bool</code>?</p>