Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C++11 constexpr string implementation

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.

like image 206
Robert Mason Avatar asked May 02 '12 16:05

Robert Mason


1 Answers

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.

like image 174
Matthieu M. Avatar answered Oct 23 '22 18:10

Matthieu M.