The important part is that all the intermediate strings used during the computation are constexpr, to guarantee that the work happens during compilation.
Also, constexpr symbols can be demoted to regular const as needed by the compiler if necessary, such as when getting a pointer to one. constexpr doesn't mean "compile-time only", it means "compile-time compatible"
Right - you can use the std::string at compile time but since it allocates dynamically you need to copy to a fixed size char[]/std::array to use at runtime.
Also, constexpr symbols can be demoted to regular const as needed by the compiler if necessary, such as when getting a pointer to one. constexpr doesn't mean "compile-time only", it means "compile-time compatible"