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?
AFAIU
std::string_view
is a dynamic object, so memory will be dynamically allocated. So how can be thisconstexpr
?
std::string_view
is not dynamically allocated. It is essentially a const char*
to the character data and the string length, combined into one object. This can obviously be constexpr
. You might be thinking of std::string
, which is dynamically allocated.
Note that
constexpr const char* str = "qwerty";
... is valid, since "qwerty"
is not dynamically allocated but has static storage duration. str
points to this string literal. If you wrap this in a std::string_view
, the str
pointer gets copied. None of this involves dynamic allocation.
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?
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 a std::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 arbitrary std::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 a std::string_view
is null-terminated at run-time, so either you (blindly) believe it, or you assume that it isn't.