Things C++26 define_static_array can't do

While C++26's std::define_static_array simplifies compile-time static array generation, it still faces significant limitations compared to the traditional 'constexpr two-step' technique.
We’ve seen previously that it’s not possible to create a constexpr global variable of container type when that container holds a pointer to a heap allocation. It’s fine to create a global constexpr std::array, or even a std::string that uses only its SSO buffer; but you can’t create a global constexpr std::vector or std::list (unless it’s empty) because it would have to hold a pointer to a heap allocation.
Think of constexpr evaluation as taking place “in the compiler’s imagination.” Since C++20 it’s fine to use new and delete at constexpr time; but there’s a firewall between constexpr evaluation and real, material runtime existence. You can’t, at runtime, get a pointer to a heap allocation that was made only “in the compiler’s imagination.”
But if you can compute a std::vector<int> at constexpr time, then you can persist its contents into a global constexpr std::array of the appropriate size. This is known as the “constexpr two-step”. C++26 will introduce a new and improved tool for this kind of compile-time array generation: std::define_static_array.
Unfortunately, C++26 define_static_array does not support several things that you can do using the “two-step.” These include:
- Non-structural types: It is defined only for structural types, excluding
std::optional,std::string, etc. - Pointers to string literals: NTTP restrictions prevent using pointers to literals as template arguments.
- Move-only types: NTTP types must be copyable, whereas the two-step can handle move-only types.
- Mutability:
define_static_arrayallocates in rodata, providing aspan<const T>, which prevents creating mutable static arrays.
Source: Hacker News














