If I were doing this, I would accept one more C++-ism and implement a user-defined string literal, so one could do:
"Some text"_s8
The underlying mechanism is even polite enough to supply a length without a horrible array template hack. (A somewhat unusual case where the C mechanism is a complete fail, the older C++ mechanism works but is incredibly ugly, and the newer C++ mechanism is actually straightforward and comprehensible.)
UDLs have one other huge benefit: you're far less likely to accidentally write a use-after-free, since otherwise there's no way to distinguish between being passed a string literal and being passed some other random char array.
Between UDLs, a little CRTP to provide the same API across a set of classes, and `#pragma GCC poison`ing half the C library, I found it very easy to completely eliminate all legacy string-handling code in a codebase.
> Its concepts regarding ownership and memory management are irreconcilable (move semantics, smart pointers, etc.), so I have to build from scratch anyway.
Absolutely not. The standard library has a zillion things, most pairs of which are independent and even unrelated. No type traits, no pairs and tuples, no std::arrays etc. - all things that are completely independent from memory management and ownership.
https://en.cppreference.com/w/cpp/language/user_literal