I tried to find the answer on SO but failed. Sorry if this is a duplicate. I will close the question then.
Could you explain the difference between:
constexpr const char Str1[] = "qwerty";
constexpr auto Str1Size = sizeof(Str1) - 1;
and
constexpr std::string_view Str2{"qwerty"};
constexpr auto Str2Size = Str2.size();
I saw the second variant today and failed to understand. AFAIU std::string_view
is a dynamic object, so memory will be dynamically allocated. So how can be this constexpr
?
Also, if these variants are really both okay, i.e. are compile-time, then what is their difference? AFAIK, Str2
will not have '\0'
and the end of it. Is it all?
std::string_view
is not dynamically allocated. It is essentially aconst char*
to the character data and the string length, combined into one object. This can obviously beconstexpr
. You might be thinking ofstd::string
, which is dynamically allocated.Note that
... is valid, since
"qwerty"
is not dynamically allocated but has static storage duration.str
points to this string literal. If you wrap this in astd::string_view
, thestr
pointer gets copied. None of this involves dynamic allocation.The null terminator is the only significant difference.
std::string_view
is not guaranteed to be null-terminated, so you lose safe access(1) to it when wrapping the character data in astd::string_view
.std::string_view
is also a standard library container, and has an interface which is much nicer to work with. You can create substrings with.substr
, etc.(1) Specifically, the null terminator is still contained in the string data, which can be accessed with
.data()
. However, an arbitrarystd::string_view
may not be null-terminated, making it unsafe and bug-prone to rely on it being null-terminated. There is also no safe way to check whether astd::string_view
is null-terminated at run-time, so either you (blindly) believe it, or you assume that it isn't.