Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Two conflict notes about member lookup occurred in base-specifier #4775

Open
xmh0511 opened this issue Jul 26, 2021 · 2 comments
Open

Two conflict notes about member lookup occurred in base-specifier #4775

xmh0511 opened this issue Jul 26, 2021 · 2 comments

Comments

@xmh0511
Copy link
Contributor

xmh0511 commented Jul 26, 2021

@opensdh
[basic.scope.class#note-1]

[Note 1: Lookup from a program point before the class-specifier of a class will find no bindings in the class scope.

[Example 1:
  
      template < class D >
      struct B {
         D::type x; // #1
      };
      struct A { using type = int; };
      struct C : A, B< C > {}; // error at #1: C​::​type not found.

— end example]

— end note]

The note and the example state that the member lookup from a program point P at a base-specifier cannot find any member.

However, the note [class.member.lookup#note-2] gives a different conclusion, that is

[Note 2: If T is incomplete, only base classes whose base-specifier appears before P are considered. If T is an instantiated class, its base classes are not dependent. — end note]

It seems like the base class A could be considered since it appears before point P in B<C>. In addition, except that P occurs in "base-specifier-list", I cannot figure out a case that there is a base class that can appear after P.

@xmh0511 xmh0511 changed the title Two conflict notes about member lookup that occurred in base-specifier Two conflict notes about member lookup occurred in base-specifier Jul 26, 2021
@opensdh
Copy link
Contributor

opensdh commented Aug 31, 2021

There's a broader issue here: the lookup for a dependent qualified name is erroneously said to take place from its definition, full stop ([temp.res.general]/1). Obviously in simple examples like

template<class T>
struct wrap {using type=T::type;};

struct A {using type=int;};

wrap<A>::type x;  // OK

the lookup for type in the definition of wrap<A> must take place from someplace after the definition—presumably it uses the point of instantiation, which should be sufficient for reachable even though we need the whole instantiation context for ADL.

Once we (I) fix that, we should come back to this to make sure it says what we want. (I know not everyone was happy being able to use lookup into base classes in other base-specifiers anyway.)

@xmh0511
Copy link
Contributor Author

xmh0511 commented Aug 31, 2021

Actually, this issue is accompanied by #4776. In that issue, I claim the definition of a class introduces a class scope rather than merely declaration does, which seems can resolve we do not lookup into base classes in other base-specifiers. I also tried to feedback this issue to core language issue, while his opinion is

The use of "declaration" there was obviously intentional, as indicated by the "(if any)" notation - the declaration is acknowledged as possibly not having a member-specification. In any event, it seems harmless to introduce the class scope with an elaborated-type-specifier, even if it will be empty. I think that it simplifies the description of qualified lookup - you look in the scope denoted by the nested-name-specifier, which will simply be empty if the class type is incomplete. You don't have to specify what happens if the nested-name-specifier, although declared, is not associated with a scope, because there's always an associated scope.

It appears to me that such an opinion is stressing this issue #4776 (comment) I have asked.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants