Title
Metafunctions should not be defined in terms of constant subexpressions
Status
wp
Section
[meta.reflection.access.queries] [meta.reflection.annotation] [meta.reflection.array]
Submitter
Jonathan Wakely

Created on 2025-10-24.00:00:00 last changed 1 month ago

Messages

Date: 2025-11-11.10:48:55

Proposed resolution:

This wording is relative to N5014.

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

    consteval bool has_inaccessible_nonstatic_data_members(info r, access_context ctx);
    

    -5- Returns: `true` if `is_accessible(`R`, ctx)` is `false` for any R in `nonstatic_data_members_of(r, access_context::unchecked())`. Otherwise, `false`.

    -6- Throws: `meta::exception` unless if

    • (6.1) — the evaluation of `nonstatic_data_members_of(r, access_context::unchecked())` is a constant subexpression would exit via an exception and or
    • (6.2) — `r` does not represent represents a closure type.

    consteval bool has_inaccessible_bases(info r, access_context ctx);
    

    -7- Returns: `true` if `is_accessible(`R`, ctx)` is `false` for any R in `bases_of(r, access_context::unchecked())`. Otherwise, `false`.

    -8- Throws: `meta::exception` unless if the evaluation of `bases_of(r, access_context::unchecked())` is a constant subexpression would exit via an exception.

  2. Modify [meta.reflection.annotation] as indicated:

    consteval vector<info> annotations_of_with_type(info item, info type);
    

    -4- Returns: A `vector` containing each element `e` of `annotations_of(item)` where `remove_const(type_of(e)) == remove_const(type)` is `true`, preserving their order.

    -5- Throws: `meta::exception` unless

    • (5.1) — the evaluation of `annotations_of(item)` is a constant subexpression would not exit via an exception and
    • (5.2) — `dealias(type)` represents a type that is complete from some point in the evaluation context.

Date: 2025-11-11.10:48:55

[ Kona 2025-11-08; Status changed: Immediate → WP. ]

Date: 2025-11-07.00:09:36

[ Kona 2025-11-06; approved by LWG. Status changed: New → Immediate. ]

Date: 2025-11-06.23:31:59

[ Kona 2025-11-06; Jonathan removes change to [meta.reflection.array] that was handled by LWG 4432. ]

Date: 2025-11-06.23:31:59
Addresses US 102-209

"is a constant (sub)expression" is incorrect now that errors are reported via exceptions.

This wording is relative to N5014.

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

    consteval bool has_inaccessible_nonstatic_data_members(info r, access_context ctx);
    

    -5- Returns: `true` if `is_accessible(`R`, ctx)` is `false` for any R in `nonstatic_data_members_of(r, access_context::unchecked())`. Otherwise, `false`.

    -6- Throws: `meta::exception` unless

    • (6.1) — the evaluation of `nonstatic_data_members_of(r, access_context::unchecked())` is a constant subexpression would not exit via an exception and
    • (6.2) — `r` does not represent a closure type.

    consteval bool has_inaccessible_bases(info r, access_context ctx);
    

    -5- Returns: `true` if `is_accessible(`R`, ctx)` is `false` for any R in `bases_of(r, access_context::unchecked())`. Otherwise, `false`.

    -6- Throws: `meta::exception` unless the evaluation of `bases_of(r, access_context::unchecked())` is a constant subexpression would not exit via an exception.

  2. Modify [meta.reflection.annotation] as indicated:

    consteval vector<info> annotations_of_with_type(info item, info type);
    

    -4- Returns: A `vector` containing each element `e` of `annotations_of(item)` where `remove_const(type_of(e)) == remove_const(type)` is `true`, preserving their order.

    -5- Throws: `meta::exception` unless

    • (5.1) — the evaluation of `annotations_of(item)` is a constant subexpression would not exit via an exception and
    • (5.2) — `dealias(type)` represents a type that is complete from some point in the evaluation context.

  3. Modify [meta.reflection.array] as indicated:

    template<ranges::input_range R>
      consteval info reflect_constant_array(R&& r);
    

    -8- Let `T` be ranges::range_value_t<R>.

    -9- Mandates: `T` is a structural type ([temp.param]), is_constructible_v<T, ranges::range_reference_t<R>> is `true`, and is_copy_constructible_v<T> is `true`.

    -10- Let V be the pack of values of type `info` of the same size as `r`, where the ith element is reflect_constant(ei), where ei is the ith element of `r`.

    -11- Let P be

    • (11.1) — If `sizeof...(`V`) > 0` is `true`, then the template parameter object ([temp.param]) of type `const T[sizeof...(`V`)]` initialized with `{[:V:]...}`.
    • (11.2) — Otherwise, the template parameter object of type array<T, 0> initialized with `{}`.

    -12- Returns: `^^`P.

    -13- Throws: `meta::exception` unless the evaluation of `reflect_constant(e)` is a constant subexpression would not exit via an exception for every element `e` of `r`.

History
Date User Action Args
2025-11-11 10:48:55adminsetmessages: + msg15683
2025-11-11 10:48:55adminsetstatus: immediate -> wp
2025-11-07 00:09:36adminsetmessages: + msg15573
2025-11-07 00:09:36adminsetstatus: new -> immediate
2025-11-06 23:31:59adminsetmessages: + msg15571
2025-10-24 18:44:37adminsetmessages: + msg15419
2025-10-24 00:00:00admincreate