title: SFINAE template specialization precedence
body: <pre><code>#include &lt;iostream&gt;
  #include &lt;array&gt;
  #include &lt;vector&gt;
  
  template &lt;typename T, typename SFINAE=void&gt;
  struct trait;
  
  template &lt;typename T&gt;
  struct trait&lt;T, decltype(
    std::declval&lt;const T&amp;&gt;().begin(),
    std::declval&lt;const T&amp;&gt;().end(),
    void()
  )&gt; {
    static const char* name() { return "Container"; }
  };
  
  template &lt;typename T, std::size_t N&gt;
  struct trait&lt;std::array&lt;T,N&gt;&gt; {
    static const char* name() { return "std::array"; }
  };
  
  int main(int argc, char* argv[]) {
    std::cout &lt;&lt; trait&lt;std::vector&lt;int&gt;&gt;::name() &lt;&lt; std::endl;
    std::cout &lt;&lt; trait&lt;std::array&lt;int,2&gt;&gt;::name() &lt;&lt; std::endl;
  }
  </code></pre>
  
  <p>I was expecting the third template to be more specialized than the second, but I got an <em>ambiguous template instantiation</em>.</p>
  
  <p>Is there a way to make the third template more specialized? Explicitly checking for whether <code>T</code> is an <code>std::array</code> in the second template won't work for me. I'm writing a library and would like users to be able to define their own specializations of the <code>trait</code>. The second template is intended to be a generic specialization for containers in absence of a more specific trait.</p>