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

CWG2917 [temp.friend] Some variadic template friend declarations should be explicitly ill-formed. #593

Open
cor3ntin opened this issue Aug 6, 2024 · 6 comments

Comments

@cor3ntin
Copy link

cor3ntin commented Aug 6, 2024

Consider

struct S {

template <typename T>
friend class Foo<T>::Nested; // #1

template <typename ...Ts>
friend class Foo<Ts>::Nested...; //#2

};

Here #1 declares a template friend declaration such that Foo<T>::Nested is a friend of S for any T, per
https://eel.is/c++draft/temp.friend#4 and https://eel.is/c++draft/temp.friend#5

However #2 doesn't really mean anything sensible. Yet there does not seem to be any wording specifying exactly what
variadic friend declarations are or are not allowed.

P2893 incorrectly claimed that #1 was ill-formed and consequently did not add wording to make #2 ill-formed.

@jensmaurer
Copy link
Member

Integrated with CWG2917.

@jensmaurer jensmaurer changed the title [temp.friend] Some variadic template friend declarations should be explicitly ill-formed. CWG2917 [temp.friend] Some variadic template friend declarations should be explicitly ill-formed. Aug 6, 2024
@cor3ntin
Copy link
Author

cor3ntin commented Aug 6, 2024

Thanks!
But, I am not sure this is sufficient. Consider

template <typename ...Ts>
struct S {
  template <typename>
  friend class Foo<Ts>::Nested...; 
};

This seems fine (and it is a template declaration and a pack expansion)
We need to say that the friend-type-specifier should not contain an unexpanded template parameter that is introduced by the template declaration.

@jensmaurer
Copy link
Member

jensmaurer commented Aug 6, 2024

Maybe: If there is a top-level pack expansion, any packs expanded by that pack expansion shall not have been introduced by the template-declaration.

@t3nsor
Copy link

t3nsor commented Aug 6, 2024

Thanks! But, I am not sure this is sufficient. Consider

template <typename ...Ts>
struct S {
  template <typename>
  friend class Foo<Ts>::Nested...; 
};

This seems fine (and it is a template declaration and a pack expansion) We need to say that the friend-type-specifier should not contain an unexpanded template parameter that is introduced by the template declaration.

Why do we want to ban this example? It has a natural interpretation that Foo<Ts...[0]>::Nested, Foo<Ts...[1]>::Nested, etc must each be a class template with one type template parameter, and each such template is declared as a friend of the S specialization.

@jensmaurer
Copy link
Member

jensmaurer commented Aug 6, 2024

@t3nsor , we don't want to ban this example, but my suggested amended wording for CWG2917 does ban it, so @cor3ntin is telling me I need to fix my wording. I've made a suggestion that feels a little better to understand than @cor3ntin 's phrasing.

@jensmaurer
Copy link
Member

CWG2917 is fixed

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

3 participants