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.
In terms of instantiation cost the reflection based solution should be much lighter and thereby preferable. On the other hand I presume that a is_specialization_of function like the one you show would be wrapped in a variable template something like this, which would have to be instantiated anyway:
This is useful both to avoid writing reflexpr() at every use and for consistency with earlier traits usage pattern. This is of course to some extent true for the s_specialization_of name too but with the variable template template parameters we propose those treat structs will be less used by regular programmers, so maybe it is ok that some non _v names are class templates and some are constexpr functions.
It is however in general very unsatisfying when similar constructs work differently depending on in which standard generation they were introduced. And it's equally unsatisfying to not use the latest possibilities to avoid such discrepancies.
If only the _v trait is standardized the way it is implemented can change between compiler versions, this is all compile time anyway. After VTTPs are in the standard we could start thinking about deprecating the non-v names, maybe. But noone has suggested deprecating the non-t names after we got type aliases so I'm not so sure. That would cause major code breakage of course.
Maybe a feature can be deprecated in a standard version and compilers get a -oldstd:C++14 kind of switch where everything deprecated in 14 and earlier is an error. Then organizations could define and change this as they modernize their code.
That's obviously another proposal, or maybe not even that as we don't standardize compiler flags.
Here is Daveed's mail and an unsent reply I made. I think it fits better in the proposal than in a reply.
Den 2022-09-16 kl. 15:49, skrev Daveed Vandevoorde:
This is useful both to avoid writing reflexpr() at every use and for consistency with earlier traits usage pattern. This is of course to some extent true for the s_specialization_of name too but with the variable template template parameters we propose those treat structs will be less used by regular programmers, so maybe it is ok that some non _v names are class templates and some are constexpr functions.
It is however in general very unsatisfying when similar constructs work differently depending on in which standard generation they were introduced. And it's equally unsatisfying to not use the latest possibilities to avoid such discrepancies.
If only the _v trait is standardized the way it is implemented can change between compiler versions, this is all compile time anyway. After VTTPs are in the standard we could start thinking about deprecating the non-v names, maybe. But noone has suggested deprecating the non-t names after we got type aliases so I'm not so sure. That would cause major code breakage of course.
Maybe a feature can be deprecated in a standard version and compilers get a -oldstd:C++14 kind of switch where everything deprecated in 14 and earlier is an error. Then organizations could define and change this as they modernize their code. That's obviously another proposal, or maybe not even that as we don't standardize compiler flags.