-
Notifications
You must be signed in to change notification settings - Fork 1.5k
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
Dependent name lookup in base class templates #3196
Comments
C++ Rules |
No unqualified name lookup through |
Dependent unqualified name lookup |
Require disambiguation anytime it could look inside a template |
FYI, one use case for base class templates is implementing types that have different APIs for different specializations, such as
I agree that in this case we generally aren't going to need to find members of The alternative to this specialization approach would require accessing the |
@zygoloid @chandlerc I thought of an argument for a particular approach. Right now name lookup with templates follows the information accumulation principle. By this I mean:
Applying this same approach to this problem gives:
So the cases are:
I think that means that in all cases unqualified names are looked up at definition time, and based on the result they get a qualification. I think the remaining possible instantiation/monomorphization errors are all errors that could otherwise occur from template instantiation/monomorphizaton. Example of the middle case:
|
Summary of issue:
Consider this code:
What happens at
#2
inx.G()
? Does it call#1
?#3
? is it an error since both names are in scope?In discussion on 2023-09-05, we decided we were most interested in three options:
#2
always calls#1
.extend
-> always have to useSelf
orself
to get to base class names. In the example,#2
always calls#1
.#2
sees both#1
and#3
and either calls#3
or it is considered ambiguous. With other instantiations, likeC({})
,#2
might only see#1
and call that.#2
ambiguous at its definition and require qualification, independent of how it is instantiated. With this rule, changing a base class to be a template would break code in all transitively-derived classes.Details:
Note that switching
T
to a checked-genericT:! type
means name lookup no longer depends on the instantiation, and so there is a better option for avoiding this problem than C++.The difference between the first two options is what happens with non-templated base classes:
With C++ rules,
#4
would see#1
and#3
.With "no unqualified name lookup through
extend
",#4
would not consider#3
and instead always resolve to#1
. To call#3
, you would have to write something likeB.F()
,Self.F()
, orself.F()
. We might also consider addingbase.F()
or evenBase.F()
. With this rule, unqualified name lookup would only find names directly declared inclass
scope, and not in any referenced or nested scope.The text was updated successfully, but these errors were encountered: