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

[temp.variadic] p6 Rearrange the rule and make the meaning clearer #5553

Open
xmh0511 opened this issue Jul 6, 2022 · 4 comments
Open

[temp.variadic] p6 Rearrange the rule and make the meaning clearer #5553

xmh0511 opened this issue Jul 6, 2022 · 4 comments

Comments

@xmh0511
Copy link
Contributor

xmh0511 commented Jul 6, 2022

[temp.variadic] p6 says

For the purpose of determining whether a pack satisfies a rule regarding entities other than packs, the pack is considered to be the entity that would result from an instantiation of the pattern in which it appears.

Actually, we also want to check the requirement for syntax where the pack appears but not just the rules for entities. For example:

template<class...T>
struct S{
   std::tuple<unsigned T...> tp;  // #1
};

At #1, we want to consider the pack T as a typedef-name, and unsigned typedef-name is not a valid combination of simple-type-specifiers summarized in [dcl.type.simple] p3, hence the combination is invalid.

Rearrange [temp.variadic] p6 to the place after [temp.variadic] p8, and change it to

For the purpose of determining whether a pack satisfies the requirements defined in this document, the pack is considered to be the element that would be used for replacing in the context of the instantiation.

template<class ...T>
struct A:T...{  //#1 ok
   std::tuple<typename T::type....> tp;  // #2  ok 
};

template<class ...U>
struct B{
   std::tuple<U&...> tp; // #3 ok 
};
B<void> b; // error

The pack T interpreted as a typedef-name can form a base-specifier at #1 and a nested-name-specifier at #2. The pack U interpreted as a typedef-name can form a type-id at #3 however the typedef-name that designates the entity void in the instantiation context forms a reference to void, which is ill-formed.

@jensmaurer
Copy link
Member

The word "entities" in the quote does not mean "entities" as specified in [basic.pre] p1, I think (for example, a typedef-name is not an entity).

And since the pattern can transform a pack into a different syntactic thing (for example, from type to expression), the "considered to be" wording is just wrong, because it mixes levels.

I think we should not try to differentiate semantic and syntactic rules here.

@xmh0511
Copy link
Contributor Author

xmh0511 commented Jul 7, 2022

In the origin rule, the "entity" is just misleading since we basically refer to these entities defined in [basic.pre] p3 when we mention it in this document. This is also implied by this phrase

regarding entities other than packs

A pack is an entity defined in [basic.pre] p3.

The clarification is just want to make the pack that appears in a construct can be first validated by the relevant grammar(syntax), such as an id-expression cannot appear in a type-specifier, and not try to differentiate semantic and syntactic rules here. The thought is to give the pack a grammatical category, in other words, clearly know whether the pack is interpreted as a typedef-name, or id-expression, or a template-name. For example, initializer-list is defined as:

initializer-list

  • initializer-clause ...opt
{ T... };

Given the construct, it is ok if T is a non-type template parameter pack that is interpreted as an id-expression but it is wrong if T is a type template parameter pack declared without template that is interpreted as a typedef-name since a typedef-name cannot be an initializer-clause. This is the intent here. The semantic rules can also be checked for the construct in both template definition context and instantiation context.

And since the pattern can transform a pack into a different syntactic thing (for example, from type to expression), the "considered to be" wording is just wrong, because it mixes levels.

As above said, consider this example

template<class...T>
void show(){
    auto c = {T...}; 
}

it is just wrong, T is interpreted as a typedef-name regardless of what the pattern is.

@jensmaurer
Copy link
Member

We agree about the intent of the rule, but what exactly is wrong with the current formulation other than the unfortunate mention of "entity" (which is defined to mean something else)?

@xmh0511
Copy link
Contributor Author

xmh0511 commented Jul 8, 2022

Except for "entities", the remaining wording seems good to me. We may fix it with other approaches.

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