c++stringc++17string-view

convert std::uint16_t to std::string_view


I want to convert std::uint16_t to std::string_view. I was expecting the following code would work:

std::string_view to_str(std::uint16_t v) {
    return std::string_view(std::to_string(v));
}

because it uses an intermediary std::string in to_str function scope. I know I can use a static storage for intermediary string like this:

std::string_view to_str(std::uint16_t v) {
    static auto str = std::to_string(v);
    return std::string_view(str);
}

I know there is another way to use char buffer and convert it to string_view but I wonder is there any better way to serve this very same purpose? Is it even logical to return string_view instead of string?


Solution

  • The problem is that std::string_view is a lightweight class that does not own the data. It is marely a view into the data held by another object (e.g. a std::string). And you need the object holding the data to be alive as long as you intend to use the string_view.

    In this line:

    return std::string_view(std::to_string(v));
    

    You return a string_view referring a temporary std::string returned from std::to_string. This temporary is then destroyed and therefore the string_view that you return is invalid (similarly to a dangling pointer/reference). Accessing it invokes undefined-behavior.

    When you use static auto str = std::to_string(v); it seems to solve this problem because the static str will stay alive after the function returns. But in fact it is not a good solution. str will only be initialize once and so the next call to to_str with a different value for v will still return a string_view for the first call.

    The solution is to simply return a std::string instead of a std::string_view (returning a string_view does not make sense because of the reason explained above).
    You will still be able to pass it to methods that expect a std::string_view.