Search code examples
c++stringc++20string-view

store a string in a constexpr struct


Is it possible to store a string in a constexpr struct:

So far I could only come up with:

struct A
{
    constexpr A(std::string_view n): m_name(n) {}   
    constexpr auto name(){ return m_name; }

    std::string_view m_name; // This might become dangling!!
} 


which is cleary only a good idea if this class is only used like this

A a = {"Hello"};
constexpr A b = {"World"};

and not like this

auto makeA(std::string n) { return A{n}; }
A a = makeA("Hello"); // Dangling internal std::string_view

I need the constexpr to construct the struct at compile time. Is it possible to make this safer at run-time, because with std::string_view, its not.


Solution

  • You might do:

    template<typename Char, Char... Cs>
    struct CharSeq
    {
        static constexpr const Char s[] = {Cs..., 0}; // The unique address
    };
    
    // That template uses the extension
    template<typename Char, Char... Cs>
    constexpr CharSeq<Char, Cs...> operator"" _cs() {
        return {};
    }
    

    See my answer from String-interning at compiletime for profiling to have MAKE_STRING macro if you cannot used the extension (Really more verbose, and hard coded limit for accepted string length).

    Then

    struct A
    {
        template <char ... Cs> 
        constexpr A(CharSeq<char, Cs...>) : m_name(CharSeq<char, Cs...>::s) {}
    
        constexpr auto name(){ return m_name; }
    
        std::string_view m_name;
    };
    

    With only valid usages similar to:

    A a = {"Hello"_cs};
    constexpr A b = {"World"_cs};