Skip to content

When does the lookup perform for a name used in default member initialization in a class template CWG1396 #4585

@xmh0511

Description

@xmh0511

This is also an issue that I recently asked on SO(https://stackoverflow.com/questions/67086569/how-does-the-lookup-rule-apply-to-a-name-that-is-used-in-a-default-member-initia). It seems no one can use the current wording to interpret this issue. In simple, the issue is:

#include <iostream>
template<class T>
struct A{
    int c = T::a;
};
struct B{
    A<B> cc;
    static const int a = 0;
};
int main(){

}

The definition of cc would cause the implicit specialization for A<B>, which in turn would cause the name lookup for T::a.

The declaration set is the result of a single search in the scope of C for N from immediately after the class-specifier of C if P is in a complete-class context of C or from P otherwise. If the resulting declaration set is not empty, the subobject set contains C itself, and calculation is complete.

According to the above code, we consider the P is not in the complete context of B, hence the member a of B cannot be found at this point. However, major implementations all accept the above example(GCC and Clang). The relevant rule of performing the lookup for a dependent name that appears in template entity is defined as:

If the name is dependent (as specified in [temp.dep]), it is looked up for each specialization (after substitution) because the lookup depends on a template parameter.

It's vague here. I infer that the name lookup for T::a might be in the definition context of the constructor of the specialization of template class A. such that could interpret the behavior of these compilers. This is hinted at in the following rule:
[class.base.init#9]

In a non-delegating constructor, if a given potentially constructed subobject is not designated by a mem-initializer-id (including the case where there is no mem-initializer-list because the constructor has no ctor-initializer), then

if the entity is a non-static data member that has a default member initializer ([class.mem]) and either
the entity is initialized from its default member initializer as specified in [dcl.init];

However, it's not explicit. I think we should give an explicit rule for when does the name lookup perform for the name in such a case.

Metadata

Metadata

Assignees

No one assigned

    Labels

    cwgIssue must be reviewed by CWG.not-editorialIssue is not deemed editorial; the editorial issue is kept open for tracking.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions