title: Type trait to get element type of std::array or C-style array
body: <p>I would like a type trait to get the element type of either a <code>std::array</code> or a plain old C-style array, eg. it should return <code>char</code> when provided with either <code>std::array&lt;char, 3&gt;</code> or <code>char[3]</code>.</p>
  
  <p>The mechanisms to do this appear to be only partially in place... I can use <code>::value_type</code> on the <code>std::array</code>, and <code>std::remove_all_extents</code> on the plain array, but I can't find a single type trait that combines both and I'm unable to write one myself.</p>
  
  <p>I've got as far as this:</p>
  
  <pre><code>#include &lt;array&gt;
  #include &lt;type_traits&gt;
  
  template &lt;class T&gt;
  using element_type =  typename std::conditional&lt;
      std::is_array&lt;T&gt;::value,
      typename std::remove_all_extents&lt;T&gt;::type,
      typename T::value_type
  &gt;::type;
  </code></pre>
  
  <p>It works just fine for <code>std::array</code>, of course:</p>
  
  <pre><code>int main()
  {
      static_assert(
          std::is_same&lt;char, element_type&lt;std::array&lt;char, 3&gt;&gt;&gt;::value,
          "element_type failed");
  }
  </code></pre>
  
  <p>but breaks when I pass it a plain array, because obviously plain arrays don't have a <code>::value_type</code>.</p>
  
  <pre><code>static_assert(std::is_same&lt;char, element_type&lt;char[3]&gt;&gt;::value, "element_type failed");
  </code></pre>
  
  <p>just gives errors like "<em>'T': must be a class or namespace when followed by '::'</em>", as you'd expect.</p>
  
  <p>If I were writing a function, I'd use <code>std::enable_if</code> to hide the offending template instantiation, but I don't see how this approach can be used in a type trait.</p>
  
  <p>What is the correct way to solve this problem?</p>