title: Is std::vector<T> a `user-defined type`?
body: <p>In 17.6.4.2.1/1 and 17.6.4.2.1/2 of the <a href="https://isocpp.org/files/papers/N3797.pdf" rel="nofollow noreferrer">current draft standard</a> restrictions are placed on specializations injected by users into <code>namespace std</code>.</p>
  
  <blockquote>
    <p>The behavior of a C
    ++
    program is undefined if it adds declarations or definitions to namespace
    std
    or to a
    namespace within namespace
    std
    unless otherwise specified. A program may add a template specialization
    for any standard library template to namespace
    std
    only if the declaration depends on a <strong>user-defined type</strong>
    and the specialization meets the standard library requirements for the original template and is not explicitly
    prohibited.</p>
  </blockquote>
  
  <p>I cannot find where in the standard the phrase <strong>user-defined type</strong> is defined.</p>
  
  <p>One option I have heard claimed is that a type that is not <code>std::is_fundamental</code> is a <strong>user-defined type</strong>, in which case <code>std::vector&lt;int&gt;</code> would be a <strong>user-defined type</strong>.</p>
  
  <p>An alternative answer would be that a <strong>user-defined type</strong> is a type that a user defines.  As users do not define <code>std::vector&lt;int&gt;</code>, and <code>std::vector&lt;int&gt;</code> is not dependent on any type a user defines, <code>std::vector&lt;int&gt;</code> is not a <strong>user-defined type</strong>.</p>
  
  <p>A practical problem this impacts is "can you inject a specialization for <code>std::hash</code> for <code>std::tuple&lt;Ts...&gt;</code> into <code>namespace std</code>?  Being able to do so is somewhat convenient -- the alternative is to create another namespace where we recursively build our hash for <code>std::tuple</code> (and possibly other types in <code>std</code> that do not have <code>hash</code> support), and if and only if we fail to find a hash in that namespace do we fall back on <code>std</code>.</p>
  
  <p>However, if this is legal, then if and when the standard adds a <code>hash</code> specialization for <code>std::tuple</code> to <code>namespace std</code>, code that specialized it already would be broken, creating a reason not to add such specializations in the future.</p>
  
  <p>While I am talking about <code>std::vector&lt;int&gt;</code> as a concrete example, I am trying to ask if types defined in <code>std</code> are ever <strong>user-defined type</strong> s.  A secondary question is, even if not, maybe <code>std::tuple&lt;int&gt;</code> becomes a <strong>user-defined type</strong> when used by a user (this gets slippery: what then happens if something inside <code>std</code> defines <code>std::tuple&lt;int&gt;</code>, and you partial-specialize <code>hash</code> for <code>std::tuple&lt;Ts...&gt;</code>).</p>
  
  <hr>
  
  <p>There is currently an <a href="https://cplusplus.github.io/LWG/lwg-active.html#2139" rel="nofollow noreferrer">open defect</a> on this problem.</p>