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.
meta::reflect_constant_array and related functionsSection: 21.4.3 [meta.define.static] Status: New Submitter: Tomasz Kamiński Opened: 2025-11-27 Last modified: 2025-12-05
Priority: Not Prioritized
View all other issues in [meta.define.static].
View all issues with New status.
Discussion:
As any array type (even of structural types) is not considered an structural type, per
13.2 [temp.param] p12, any invocation of reflect_constant_array/define_static_array
with a multidimensional array or span of arrays is ill-formed due to the Mandates in
21.4.3 [meta.define.static] p8 that requires range value type to be structural.
As a consequence, constant_of currently supports only single-dimensional arrays
(reflect_constant_array strips outermost extents), while multi-dimensional arrays are
rejected.
Furthermore, define_static_object currently uses define_static_array(span(addressof(t), 1)).data(),
for array types. Since for T[N] input this creates an multidimensional T[1][N] constant parameter
object, this function does not support arrays at all. Creating a distinct template
parameter object leads to emission of (otherwise unnecessary) additional symbols, and breaks the
invariant that for all supported object types &constant_of(o) == define_static_object(o).
We should use reflect_constant_array for arrays directly.
The Throws clause of reflect_constant_array was updated to include any exception
thrown by iteration over range.
[2025-12-05; LWG telecon. Wording tweaks]
Proposed resolution:
This wording is relative to N5014 amended with changes from LWG 4432(i).
Modify 21.4.3 [meta.define.static] as indicated:
template<ranges::input_range R> consteval info reflect_constant_array(R&& r);
[…]-8- Let
beTranges::range_value_t<R>andei be.static_cast<T>(*iti), where iti is an iterator to the ith element ofr-9- Mandates:
Tis a structural type (13.2 [temp.param]),is_constructible_v<T, ranges::range_reference_t<R>>istrue, andTsatisfiescopy_constructible-10- Let
Vbe the pack of values of typeinfoof the same size asr, where the ith element is.
reflect_constant(ei)-11- Let
Pbe
- (11.1) — If
sizeof...(V) > 0istrue, then the template parameter object (13.2 [temp.param]) of type constT[sizeof...(V)]initialized with.{[:V:]...}- (11.2) — Otherwise, the template parameter object of type
const array<T, 0>initialized with{}.-12- Returns:
^^P.-13- Throws: Any exception thrown by the evaluation of any
ei, ormeta::exceptionif evaluation of anywould exit via an exception.reflect_constant(ei)
template<class T> consteval const remove_cvref_t<T>* define_static_object(T&& t);
-15- Effects:Equivalent to:
using U = remove_cvref_t<T>; if constexpr (meta::is_class_type(^^U)) { return addressof(meta::extract<const U&>(meta::reflect_constant(std::forward<T>(t)))); } else { return define_static_array(span(addressof(t), 1)).data(); }