We propose a way to spell a universal template parameter kind. This would allow for a generic apply and other higher-order template metafunctions, and certain typetraits.
There is a new style of disambiguation of a UTP that is spelled typename U, which is a real and big problem for disambiguation to type inside template parameter lists, where a leading typename token introduces a template parameter of kind type:
template<__anykind U> class X {
template void f();
template void g();
};
It is obvious that f takes one template parameter of kind type. But g could either do the same or the 'typename' could be seen as disambiguating the outer U as a type, so g would take a NTTP of the type U.
I don't have a good answer to this off the bat but I think we must have one for the next paper version.
Some bad answers are:
Use class instead of typename if you want g to have a template parameter of kind type, let typename mean to disambiguate U.
Don't allow disambiguation of U in a template parameter list, users have to do it before the declaration of g.
Combine both, make the code as written ill-formed: To get same behaviour as f use class, to get disambiguation make a separate type alias.
Note that today, without UDP, there is always a syntactical difference between disambiguation and declaration as there are no dependent names withtout :: so compilers uses this to distinguish the cases. Here is an example:
There is a new style of disambiguation of a UTP that is spelled typename U, which is a real and big problem for disambiguation to type inside template parameter lists, where a leading typename token introduces a template parameter of kind type:
template<__anykind U> class X { template void f();
template void g();
};
It is obvious that f takes one template parameter of kind type. But g could either do the same or the 'typename' could be seen as disambiguating the outer U as a type, so g would take a NTTP of the type U.
I don't have a good answer to this off the bat but I think we must have one for the next paper version.
Some bad answers are:
Use class instead of typename if you want g to have a template parameter of kind type, let typename mean to disambiguate U.
Don't allow disambiguation of U in a template parameter list, users have to do it before the declaration of g.
Combine both, make the code as written ill-formed: To get same behaviour as f use class, to get disambiguation make a separate type alias.
Note that today, without UDP, there is always a syntactical difference between disambiguation and declaration as there are no dependent names withtout :: so compilers uses this to distinguish the cases. Here is an example:
https://godbolt.org/z/f5dd48Pae