Search code examples
c++language-lawyerstandardsc++20

Is placeholder for the deduced class type of non-type template parameter a C++20 feature?


With the addition of non-type template parameter of class type into the C++20 standard (P0732R2) was introduced the possibility to declare a non-type template parameter using a placeholder for deduced class type for non-type template parameter [dcl.type.class.deduct]§2:

A placeholder for a deduced class type can also be used in the type-specifier-seq in the new-type-id or type-id of a new-expression, as the simple-type-specifier in an explicit type conversion (functional notation), or as the type-specifier in the parameter-declaration of a template-parameter.

What is bolded is the addition of P0732R2 to the standard. This allows such code:

template <class T>
struct x{
   constexpr x(T){}
};

template <x v>
struct y {};

y <1> b;

Code that compiles with GCC.

I thought about using this feature in new code, but there is 3 reasons that makes me think that actually this feature was intended to be removed from the standard:

  • It is not well integrated in the standard, for example, the unchanged standard wording for partial ordering of function templates makes it impossible to partially specialize a class template similar to y because the synthesized argument for the template parameter v must have a unique invented type (the synthesized argument used during partial ordering of class template specializations) ;

  • This syntax for placeholder inside a parameter looks like the "short concept syntax" of the concept-TS. This syntax has been changed to the "adjective syntax" concept-name auto after the addition of P0732R2 to the standard;

  • On std-discussion, it looked like not all committee members are aware of this feature.

Is placeholder for the deduced class type of non-type template parameter a C++20 feature ?


Solution

  • Is placeholder for the deduced class type of non-type template parameter a C++20 feature ?

    Yes. [temp.param]/6 is quite clear about this:

    A non-type template-parameter shall have one of the following (possibly cv-qualified) types:

    • a structural type (see below),
    • a type that contains a placeholder type ([dcl.spec.auto]), or
    • a placeholder for a deduced class type ([dcl.type.class.deduct]).

    As for your concerns.

    It is not well integrated in the standard, for example, the unchanged standard wording for partial ordering of function templates makes it impossible to partially specialize a class template [...]

    Yes, language additions are frequently incomplete and lead to language issues. A more pressing one is the limitation on what kinds of types can be used as non-type template parameters, a limitation that prohibits std::string, std::tuple, and std::optional and the moment. These will be resolved in due time.

    This syntax for placeholder inside a parameter looks like the "short concept syntax" of the concept-TS

    This is just what CTAD syntax looks like.

    On std-discussion, it looked like not all committee members are aware of this feature.

    So?