title: std::is_constructible immediate context and friend declarations
body: <p>Recently I attempted to detect existence of specific private constructors and ran into the issue that <code>std::is_constructible</code> only checks the immediate context and thus would not recognize anything such constructors. After some research I did see that one answer <a href="https://stackoverflow.com/a/49269069/2085551">here</a> mentioned that the proper way is to friend the class in question with <code>std::is_constructible</code> to allow it to have access.</p>
  
  <p>To test if this method worked, I attempted the following test code</p>
  
  <pre><code>#include &lt;type_traits&gt;
  
  class A {
  private:
    template&lt;typename, typename ...&gt;
    friend struct std::is_constructible;
  
    A() = default;
  };
  
  int main() {
    static_assert(std::is_constructible&lt;A&gt;::value);
    static_assert(std::is_constructible_v&lt;A&gt;);
  }
  </code></pre>
  
  <p>Interestingly, this method did appear to work with <code>std::is_constructible</code> in Visual Studio 2017, though I then began to encounter issues with <code>std::is_constructible_v</code>. In their implementation, rather than using an alias template to the actual struct <code>std::is_constructible</code> itself, they instead call the intrinsic used internally directly which in turn ignores the friend declaration.</p>
  
  <p>Thinking that this was a bug with their standard library implementation, I then tested in other compilers and found that neither clang nor gcc were able to pass this assertion in any case, causing me to wonder if it is even supposed to work like this at all (some of the comments on the linked post seem to suggest it's a bug while others say it should not take friend declarations into account).</p>
  
  <p>Thus, the main question is should this code work correctly (as in should it be able to access the private constructor and pass the assertions) with way the standard defines the access being limited to an immediate context? A similar question was also posed <a href="https://stackoverflow.com/q/28085847/2085551">here</a>, the main thing I am unsure about is the exact definition intended by an "immediate context" in this case since this is slightly different than the example in the linked question.</p>
  
  <p>A relevant passage from N4713 23.15.4.3.8 [meta.unary.prop]/8:</p>
  
  <blockquote>
    <p>Access checking is performed as if in a context unrelated to T and any
    of the Args. Only the validity of the immediate context of the
    variable initialization is considered.</p>
  </blockquote>