cplusplus / CWG

Core Working Group
23 stars 7 forks source link

CWG2806 [temp.res.general] Is a type-requirement a type-only context? #436

Closed brevzin closed 7 months ago

brevzin commented 9 months ago

Reference (section label): [temp.res.general]

Issue description: Reduced from StackOverflow (https://stackoverflow.com/questions/77266478/need-of-template-specifier-to-treat-a-type-as-a-dependent-template-name-in-conce), is this concept valid:

template <typename T>
concept C = requires {
    typename T::type<void>;
};

gcc accepts, clang and msvc want template to disambiguate there.

With a strict reading of the rules (after down with typename!), the [temp.names]/3 rule for when < opens a template-argument-list includes type-only contexts but excludes nested-name-specifiers. But the grammar we have today for a type-requirement is:

typename nested-name-specifier_opt type-name

So it just doesn't count.

Suggested resolution: Include type-requirement as a type-only context in [temp.res.general]. Alternatively, consider type-requirement to be a context where the < introduces a template-argument-list in [temp.names].

t3nsor commented 9 months ago

[temp.res.general]/4 is expressed in terms of terminal names, so we also need to say in [expr.prim.req.type] that the terminal name of a type-requirement is that of its type-name.

(Note that the nested-name-specifier exception here is a red herring. The nested-name-specifier is just T::, so it's not the thing that comes right before the <.)

t3nsor commented 9 months ago

Actually, "terminal name" is defined in terms of component names, so what we really need to say is that the component name of a type-requirement is that of its type-name.

jensmaurer commented 9 months ago

CWG2806