Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>This fails because of the two-phase name lookup in C++.</p> <p>In phase one, when the template is initially parsed, long before it is instantiated, the compiler parses the template and looks up any non-dependent names. <code>S::P</code> is a non-dependent name, so the compiler tries to look it up, but fails because it is private. </p> <p>In phase 2, when the template is instantiated, the compiler will lookup any dependent names, which can vary from template to template. </p> <p>Clang is fairly strictly conforming to the two-phase name lookup. However, MSVC has a template parsing model that delays nearly every lookup to instantiation time, which is part of phase 2. This delay is why your example would compile with MSVC(which is non-conforming) and not in clang. Here is a link with more information:</p> <p><a href="http://blog.llvm.org/2009/12/dreaded-two-phase-name-lookup.html" rel="nofollow">The Dreaded Two-Phase Name Lookup</a></p> <p>Also, here are the sections from the C++ standard where it describes the two-phase lookup.</p> <p>14.6.8:</p> <blockquote> <p>When looking for the declaration of a name used in a template definition, the usual lookup rules (3.4.1, 3.4.2) are used for non-dependent names. The lookup of names dependent on the template parameters is postponed until the actual template argument is known.</p> </blockquote> <p>14.6.9:</p> <blockquote> <p>If a name does not depend on a template-parameter (as defined in 14.6.2), a declaration (or set of declarations) for that name shall be in scope at the point where the name appears in the template definition; the name is bound to the declaration (or declarations) found at that point and this binding is not affected by declarations that are visible at the point of instantiation.</p> </blockquote> <p>Then the part of 3.4 Name lookup applicable to you:</p> <blockquote> <p>The access rules (clause 11) are considered only once name lookup and function overload resolution (if applicable) have succeeded. Only after name lookup, function overload resolution (if applicable) and access checking have succeeded are the attributes introduced by the name’s declaration used further in expression processing (clause 5).</p> </blockquote> <p>Its clear from reading these parts that your program is ill-formed. The only thing the standard states that should be postponed until instantiation is the lookup of a dependent name. Non-dependent names go through the usual name lookup, which includes access rules.</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload