Skip to content

CWG1670 [class.member.lookup] Name lookup for conversion functions declared using a placeholder #736

@t3nsor

Description

@t3nsor

Full name of submitter: Brian Bi

Issue description: It is not clear whether a conversion function named operator auto can be found by name lookup for operator int if int is the deduced return type.

struct A {
    operator auto();
};

A::operator auto() { return 0; }  // all compilers accept

int main() {
    A().operator int();  // only GCC accepts
    A().operator auto();   // only Clang and MSVC accept
}

[dcl.spec.auto.general]/1 states that a placeholder type will be "replaced later". After the placeholder has been deduced to int, it is not clear whether the name of the conversion function is now "the same" ([basic.pre]) as operator int due to replacement of auto by int. Equally, it is not clear whether, after such replacement, the conversion function should be found by lookup for operator auto.

Discussion: Perhaps we should ban lookup of conversion-function-ids that contain undeduced placeholder types. This seems to be an arcane feature, and removing it would make conversion functions more consistent with other functions that have placeholder return types, which have only two "states" during compilation: a state in which attempting to refer to it is ill-formed, and a later state in which only its deduced return type can be observed, not the fact that it was originally declared using a placeholder.

Similarly to other functions that have placeholder return types, all implementations allow operator auto to be declared in the class definition and then defined out of line using the name operator auto. However, the conversion-function-id used to introduce the definition is not looked up ([dcl.meaning.general]/3.4), so banning lookup of operator auto will not affect the ability to define it out of line.

Lookup using a concrete type should find conversion functions that were declared with placeholder types if the placeholder has been deduced; the above call A().operator int(); should be well-formed.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions