6
votes

C++17 has given us string_view to optimise the scenarios where we were needlessly allocating memory when we only need a view of the underlying sequence of characters. The wisdom is that you can almost always replace const std::string& with std::string_view. Consider the following example:

char foo(const std::string& str)
{
    return str[0];
}

The above is a valid function for all values of std::string. However, if we change this to:

char foo(std::string_view sv)
{
    return sv[0];
}

We have triggered Undefined Behaviour for strings of size 0! This has a note at the end:

Unlike std::basic_string::operator[], std::basic_string_view::operator[] (size()) has undefined behavior instead of returning CharT().

Does anyone know why the behaviour is incongruous for the indexing operator?

1
Isn't the former str[0] also undefined, same as *begin() or front()? - Tas
This was my TIL. str[0] was undefined in c++03. However, in c++11 for pos == size(), a reference to character with value CharT() is returned. More details here: en.cppreference.com/w/cpp/string/basic_string/operator_at - skgbanga
"The wisdom is that you can almost always replace const std::string& with std::string_view" <== source? - xaxxon
@xaxxon I'd call that common sense. Unless another compelling reason for the existence of string_view comes to mind - Passer By
fair enough. In your answer to @PasserBy you said "you need something that's not const", but in the question I said "const std::string&" so that is out of the consideration. - skgbanga

1 Answers

8
votes

The difference is a std::string is guaranteed to be NUL terminated - a view is not. Therefor a std::string always has a valid value at the 0th position.

For a std::string:

If pos == size(), a reference to the character with value CharT() (the null character) is returned.

http://en.cppreference.com/w/cpp/string/basic_string/operator_at