Is there a way to implement strings to work both at compile time and run time?
AFAIK for a class to be constexpr constructed it needs to have a trivial destructor. However, this proves difficult when we're dealing with strings. If the string is NOT constexpr, then it needs to deallocate memory. However, if it IS constexpr, then it is statically allocated and shouldn't be deleted, thus allowing a trivial destructor.
However, it's not possible to say "Hey, Compiler! If I'm constexpr, you don't need to destruct me!" Or is it?
It would be something like the following:
class string {
private:
char * str;
public:
template<std::size_t l>
constexpr string(const char (&s)[l]) : str(&(s[0])) {}
string(const char * s) { str = strdup(s); }
static if (object_is_constexpr) {
~string() = default;
}
else {
~string() { free(str); }
}
};
The closest I've been able to come is having two separate types, string and constexpr_string, a user-defined literal _string returning constexpr_string, and a user-defined implicit conversion from constexpr_string to string.
This isn't very nice though, as const auto s = "asdf"_string;
works but const string s = "asdf"_string;
does not. Additionally, a reference/pointer to a constexpr_string won't convert. Inheritance either way causes un-intuitive "gotcha"s, and doesn't resolve the first problem.
This seems like it should be possible, as long as the compiler were to TRUST the programmer that the constexpr didn't need to be destructed.
If I have a misconception let me know.
It's not only a matter of destruction.
A constexpr
operation should only call other constexpr
operations and new
, malloc
etc... are not constexpr
. Note that this is a statically checked property and does not depend on the runtime argument, so the call to such function must be absent altogether, and not merely hidden in a branch that is (supposedly) not taken.
As such, it will never be possible to get a constexpr
string
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With