Repository navigation
CWG3099 [temp.inst] Instantiation of type aliases from alias templates unspecified #782
Description
Activity
Lol I knew this sounded familiar 🤣
I agree that it ought to be possible to form a reflection of an alias template specialization (whether through
substituteor otherwise) without instantiating the underlying entity. The implemented behavior in the clang prototype is what was expedient at the time, and something that I meant to look into fixing.If we like the suggested direction, we should make sure to gather feedback from implementers to check if there are concerns, especially since both experimental implementations separately arrived at the same (possibly undesirable) behavior.
IMO, the
substituteinvocation in the example should throw (and since nothing is caught, the program is ill-formed).I consider "alias templates" to be "substituted" (which, as Hubert notes, is an immediate-context process), not "instantiated" (the process that starts a new context).
hubert-reinterpretcast commented
on Oct 20, 2025 MemberAuthorMore actionsI consider "alias templates" to be "substituted" (which, as Hubert notes, is an immediate-context process), not "instantiated" (the process that starts a new context).
That is a lot more clear in a pre-P2996 world where alias templates are quite transparent. With P2996, we are supposed to have an entity (a type alias with a unique identity) associated with the reflection of each specialization of an alias template. The creation of the entity's definition sounds like "instantiation" to me.
hubert-reinterpretcast commented
on Oct 20, 2025 MemberAuthorMore actionsIt seems the EDG implementation on Compiler Explorer does not maintain the identity of the alias template specialization (https://godbolt.org/z/efbo8T18o):
#include <experimental/meta> using namespace std::meta; template <typename T> using A = T *; static_assert(substitute(^^A, {^^int}) != ^^int *); // EDG rejects
I don't think there is a need to leave the immediate context here. It cannot fail once the substitution of the underlying type-id has succeeded. The type alias being created is just a convenient item to be able to query the origin of the type...
It seems the EDG implementation on Compiler Explorer does not maintain the identity of the alias template specialization (https://godbolt.org/z/efbo8T18o):
#include <experimental/meta>
using namespace std::meta;
template
using A = T *;static_assert(substitute(^^A, {^^int}) != ^^int *); // EDG rejects
Right. I haven't updated the EDG implementation in a loooong time. It's quite out of date wrt. the latest P2996 versions.
hubert-reinterpretcast commented
on Oct 20, 2025 MemberAuthorMore actionsI don't think there is a need to leave the immediate context here. It cannot fail once the substitution of the underlying type-id has succeeded. The type alias being created is just a convenient item to be able to query the origin of the type...
If we want this direction, I think the wording change is to update https://wg21.link/temp.alias#2.sentence-2 to say:
Any other template-id that names a specialization of an alias template is a typedef-name for a type alias; such a template-id is ill-formed if forming the associated type results in substitution failure.
Reacted by Daveed VandevoordeThat sounds good to me — thank you!
Reacted by Hubert Tonghubert-reinterpretcast commented
on Oct 23, 2025 MemberAuthorMore actions@jensmaurer, as this is new from C++26, I am interested in having this addressed for plenary in Kona.
- Reacted by Hubert Tong
- changed the title
[-][temp.inst] Instantiation of type aliases from alias templates unspecified[/-][+]CWG3099 [temp.inst] Instantiation of type aliases from alias templates unspecified[/+]on Oct 23, 2025 There's no such thing as substitution failure in the standard. What we have is deduction failure (https://eel.is/c++draft/temp.deduct.general#8).
hubert-reinterpretcast commented
on Oct 24, 2025 MemberAuthorMore actionsThere's no such thing as substitution failure in the standard.
We already use the term "substitution failure" in various places where we describe situations in which substitution is performed.
There's no such thing as substitution failure in the standard.
We already use the term "substitution failure" in various places where we describe situations in which substitution is performed.
Okay, you're right. We use it mostly in notes, but I do see a reference from normative text in ([expr.prim.req.general]/5):
[...] If the substitution of template arguments into a requirement would always result in a substitution failure, the program is ill-formed; no diagnostic required.
Whoever wrote this obviously thought that "substitution failure" was a defined term. Otherwise, they would have chosen more straightforward wording, "If the substitution [...] would always fail, [...]".
Perhaps we should consider providing a definition.
Full name of submitter (unless configured in github; will be published with the issue): Hubert Tong
Reference (section label): [temp.alias], [temp.inst]
Link to reflector thread (if any): N/A
Issue description:
P2996 added the idea that a type alias can result from instantiation of an alias template; however, the timing of the instantiation (and its relation to the immediate context) is unspecified.
Some thoughts:
Consider https://godbolt.org/z/Wof7fcr3a:
Observations:
substituteis used to form the specialization.Suggested resolution:
Gather input from P2996 paper authors.