Using a consteval function parameter in constexpr context
17:51 07 May 2026

I'm trying to use a consteval function parameter in constexpr context:

consteval auto foo(int size) {

        std::array arr; // error: size is not constexpr

        auto const_size = std::meta::reflect_constant(size);
        auto array_type = std::meta::substitute(^^std::array, {^^int, const_size});

        [:array_type:] arr; // error: array_type is not constexpr

        // I can even inspect the array type in call foo(10):
        // error: uncaught exception ‘&"std::array"[0]’
        throw std::meta::display_string_of(array_type).data();
}

I can materialize array with std::meta::reflect_constant_array or std::meta::define_static_array but get my size erased:

consteval auto foo(int size) {
        auto helper = std::ranges::views::iota(0, size);

        auto arr_refl = std::meta::reflect_constant_array(helper);
        auto arr = std::meta::extract(arr_refl);

        // I can also inspect the static array in call foo(5):
        // error: uncaught exception ‘&"const int [5]{0, 1, 2, 3, 4}"[0]’
        throw std::meta::display_string_of(arr_refl).data();
}

Obviously it's easily achieved with non-type template parameters:

template consteval auto foo() { std::array arr; }

Notice that we do get a way of instantiating non-type template parameters with non-constexpr values: the (possible) implementation of std::meta::define_static_array uses extract() to implicitly instantiate template<> __fixed_array with non-constexpr values of r to put them in static storage:

// From P3491R3
template 
inline constexpr T __fixed_array[sizeof...(Vs)]{Vs...};

template 
consteval auto reflect_constant_array(R&& r) -> info {
        auto args = vector{^^ranges::range_value_t};
        for (auto&& elem : r) {
                args.push_back(reflect_constant(elem));
        }
        return substitute(^^__fixed_array, args);
}

template 
consteval auto define_static_array(R&& r)
    -> span const>
{
    using T = ranges::range_value_t;

    // produce the array (info)
    auto array = meta::reflect_constant_array(r);

    // turn the array into a span
    return span(extract(array), extent(type_of(array)));
}

It seems like the language strongly resists the idea of making function parameters constexpr or reflecting values known to evaluator as constexpr variables. And I don't see exactly why it's disallowed.

Even with static reflections you only get a tiny extract() trick which (despite knowing the exact type from info) requires explicit return template parameter, effectively covering the loophole.

c++ reflection constexpr consteval c++26