cplusplus / CWG

Core Working Group
23 stars 7 forks source link

[temp.spec.general] Declaring functions in templates via type aliases that assuredly declare functions despite type-dependence #520

Open hubert-reinterpretcast opened 6 months ago

hubert-reinterpretcast commented 6 months ago

Full name of submitter (unless configured in github; will be published with the issue): Hubert Tong

Reference (section label): temp.spec.general

Link to reflector thread (if any): N/A

Issue description: In [temp.spec.general]/8, we say:

If a function declaration acquired its function type through a dependent type without using the syntactic form of a function declarator, the program is ill-formed.

However, consider a case like the following:

template <typename T>
using Ident = T;

template <typename T>
struct A {
  typedef T F();
  static Ident<F> f;
};
int (*af)(void) = A<int>::f;

The declaration acquired its function type "through" a dependent type Ident<F> and the declaration does so without using the syntactic form of a function declarator; therefore, the above is ill-formed. It does not appear that implementations diagnose such a case though: https://godbolt.org/z/YxG69n3s1.

Suggested resolution: Perhaps a function declarator being present without reliance upon the template arguments should be sufficient.

frederick-vs-ja commented 6 months ago

If Ident is replaced with std::type_identity_t then all implementations agree on that the program is ill-formed. Not sure whether the difference is already addressed.

Perhaps we should say the "syntactic form" is determined after expansion of type aliases.

jensmaurer commented 6 months ago

@hubert-reinterpretcast , as it stands, I'm not seeing why this should be a core issue. The wording seems very clear that you need the "syntactic form of a function declarator" for something with dependent type to be a function declaration, and I have to assume this was intentional. I don't think there is evidence that this requirement was supposed to be relaxed with the introduction of alias templates, despite widespread implementation fall-out.

I'd suggest you write a paper targeted at EWG.

frederick-vs-ja commented 6 months ago

251 seems related.

I think "syntactic form of a function declarator" in [temp.spec.general] and "reference type" in [temp.deduct.call] should be consistently handled (currently whether [temp.alias] p2 applies is not very clear in both places).

jensmaurer commented 5 months ago

[temp.alias] p2 talks about "equivalent to the associated type", which seems to be far beyond "the syntactic form".