This page is a snapshot from the LWG issues list, see the Library Active Issues List for more information and the meaning of New status.

4564. Clarify when constant_of throws

Section: 21.4.7 [meta.reflection.queries] Status: New Submitter: Marek Polacek Opened: 2026-03-31 Last modified: 2026-04-04

Priority: Not Prioritized

View all other issues in [meta.reflection.queries].

View all issues with New status.

Discussion:

The constant_of specification in 21.4.7 [meta.reflection.queries] p9 says:

Throws: meta::exception unless either r represents an annotation or [: R :] is a valid splice-expression (7.5.9 [expr.prim.splice]).

But if we have [:^^X:] where X is a template, the splice-expression is valid, but we should still throw, because constant_of on a template declaration makes no sense. Since we call reflect_constant on the splice as per:

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 :]);
}

the code would be ill-formed anyway, but it seems clearer to say something like:

Throws: meta::exception unless either r represents an annotation or [: R :] is a valid splice-expression that doesn't designate a template.

Proposed resolution:

This wording is relative to N5032.

  1. Modify 21.4.7 [meta.reflection.queries] as indicated:

    consteval info constant_of(info r);
    

    -7- Let R be a constant expression of type info such that R == r is true. If r represents an annotation, then let C be its underlying constant.

    -8- 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 :]);
    }
    

    -9- Throws: meta::exception unless either r represents an annotation or [: R :] is a valid splice-expression (7.5.9 [expr.prim.splice]) that doesn't designate a template.