title: Access to own private constructors via derived class constructor inheritance
body: <p><a href="https://godbolt.org/z/Wx5YKh" rel="noreferrer">Consider</a>:</p>
  <pre><code>struct B {
      void f();
  private:
      B(int, int = 0);
  };
  struct D : B { using B::B; };
  void B::f() {
      auto a = D{0};
      auto b = D(0);
      auto c = D(0, 0);
      D x{0};
      D y(0);
      D z(0, 0);
  }
  </code></pre>
  <p>GCC accepts (since 7.1; previously rejects all).
  Clang accepts <code>b</code> and <code>xyz</code> but rejects <code>a</code> and <code>c</code>.
  MSVC rejects all in C++14 mode but accepts all in C++17 mode.</p>
  <p>Which compiler(s) are correct? Did the rules change between C++14 and C++17 - if so, why in C++14 is <code>B::f</code> not allowed to access its own constructors (named via <code>D</code>)? And why does Clang only accept the (function-style) cast at <code>b</code> and not list-initialization at <code>a</code> or constructor call at <code>c</code>?</p>
  <p>(Making <code>B</code> a <code>friend</code> of <code>D</code> makes Clang accept, except for older versions (3.8 and older), and MSVC in C++14 mode. It doesn't make a difference to gcc.)</p>
  <p>Now, I know that <a href="https://timsong-cpp.github.io/cppwp/n3337/class.inhctor#4" rel="noreferrer">C++14 says</a>:</p>
  <blockquote>
  <p>A constructor so declared [as an inheriting constructor] has the same access as the corresponding constructor in [the base class] X.</p>
  </blockquote>
  <p>And in C++17 the rules were simplified, clarified and <a href="http://eel.is/c++draft/namespace.udecl#19" rel="noreferrer">moved to [namespace.udecl]</a>:</p>
  <blockquote>
  <p>A using-declarator that names a constructor does not create a synonym; instead, the additional constructors are accessible if they would be accessible when used to construct an object of the corresponding base class, and the accessibility of the using-declaration is ignored.</p>
  </blockquote>
  <p>So, I thought that perhaps &quot;has the same access as&quot; means the inherited constructors are <code>private</code> to <code>D</code> so only accessible to <code>D</code> (and its friends), rather than <code>private</code> to <code>B</code> (and so accessible to <code>B::f</code>) as are their corresponding constructors in <code>B</code>. But under that interpretation, one would be able to subvert access checking and access private constructors of one's base class by inheriting them. So surely in C++14 the intent of the wording is the same as expressed more clearly in C++17 - but then why does MSVC change its behavior depending on language version?</p>