This is an unofficial snapshot of the ISO/IEC JTC1 SC22 WG21 Core Issues List revision 115e. See http://www.open-std.org/jtc1/sc22/wg21/ for the official list.
2024-11-11
(From submission #599.)
Consider:
template <typename U> constexpr bool foo = U::b; template <class T> struct A { A() requires(foo<A>) {} static constexpr bool b = true; }; A<int> a;
All implementation accept, but there is no normative wording prescribing the lookup context for U::b.
Proposed resolution (approved by CWG 2024-09-13):
Change in 6.5.5.1 [basic.lookup.qual.general] paragraph 3 as follows:
Qualified name lookup in a class, namespace, or enumeration performs a search of the scope associated with it (6.5.2 [class.member.lookup]) except as specified below. Unless otherwise specified, a qualified name undergoes qualified name lookup in its lookup context from the point where it appears unless the lookup contexteitherIf nothing is found by qualified lookup for a member-qualified name that is the terminal name (7.5.5.2 [expr.prim.id.unqual]) of a nested-name-specifier and is not dependent, it undergoes unqualified lookup.
- is dependent and is not the current instantiation (13.8.3.2 [temp.dep.type]), in which case the lookup is done from the point of instantiation (13.8.4.1 [temp.point]), or
- is
not a class or class templatea type that is neither a class nor an enumeration, in which case unqualified lookup is performed. [ Note: Such a qualified name can be used to name a destructor (7.5.5.5 [expr.prim.id.dtor]). -- end note ]
Additional notes (September, 2024)
The proposed wording appears to make the following example unintentionally well-formed:
int n; using T = int; int m = T::n;
CWG 2024-11-08
The example above is already ill-formed per 6.5.5.1 [basic.lookup.qual.general] paragraph 1.