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.
constant_of throwsSection: 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::exceptionunless eitherrrepresents 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::exceptionunless eitherrrepresents an annotation or[: R :]is a valid splice-expression that doesn't designate a template.
Proposed resolution:
This wording is relative to N5032.
Modify 21.4.7 [meta.reflection.queries] as indicated:
consteval info constant_of(info r);-7- Let
-8- Effects: Equivalent to:Rbe a constant expression of typeinfosuch thatR == ristrue. Ifrrepresents an annotation, then letCbe its underlying constant.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::exceptionunless eitherrrepresents an annotation or[: R :]is a valid splice-expression (7.5.9 [expr.prim.splice]) that doesn't designate a template.