This is an unofficial snapshot of the ISO/IEC JTC1 SC22 WG21 Core Issues List revision 118f. See http://www.open-std.org/jtc1/sc22/wg21/ for the official list.

2025-11-07


3111. Template parameter objects of array type

Section: 13.2  [temp.param]     Status: ready     Submitter: Dan Katz     Date: 2025-10-30

(From submission #791.)

Constant template parameters of array type decay to pointers, thus template parameter objects of array type are never created this way. However, with reflection, 21.4.3 [meta.define.static] paragraph 11 does ask for such objects, which are underspecified.

Proposed resolution (approved by CWG 2025-11-07):

  1. Change in 13.2 [temp.param] paragraph 13 as follows:

    Certain constructs refer to template parameter objects, which are distinct objects with static storage duration and non-volatile const type. No two such objects have template-argument-equivalent values (13.6 [temp.type]). An id-expression naming a constant template parameter of class type T denotes a static storage duration the template parameter object of type const T, known as a template parameter object, which is template-argument-equivalent (13.6 [temp.type]) to the corresponding template argument after it has been converted to the type of the template parameter (13.4.3 [temp.arg.nontype]). No two template parameter objects are template-argument-equivalent.

    [ Note: There can be template parameter objects of array type (21.4.3 [meta.define.static]), but such an object is never denoted by an id-expression that names a constant template parameter. -- end note ]

    [Note 2: If an id-expression names a non-reference constant template parameter, then it is a prvalue if it has non-class type. Otherwise, if it is of class type T, it is an lvalue and has type const T (7.5.5.2 [expr.prim.id.unqual]). —end note] [ Example: ... ]
  2. Change in 21.4.7 [meta.reflection.queries] paragraph 7 as follows:

    Effects: Equivalent to:
      if constexpr (is_annotation(R)) {
        return C;
      } else if constexpr (is_array_type(type_of(R)) {
        return reflect_constant_array([: R :]);
      } else if constexpr (is_function_type(type_of(R)) {
        return reflect_function([: R :]);
      } else {
        return reflect_constant([: R :]);
      }