Consider this program
class Character
{
public:
virtual std::string GetClassName() const = 0;
};
class Warrior : public Character
{
std::string GetClassName() const override { return "Warrior"; }
};
Here’s what happens
"Warrior"is stored as a C-style literal.- When the method is called, a new
std::stringis constructed from the C-style literal std::stringis deleted via its destructor- Repeat for however many times this method is called (which is a lot btw)
This is additional overhead for simply getting a string. This is inefficient.
Fortunately, we can do better.
Since we don’t modify the string, this is a good justification to use std::string_view.
Introducing std::string_view (C++17)
std::string_view provides read-only access to a:
- C-style string literal
std::stringstd::string_view(itself!)
Let’s refactor the above program using std::string_view
class Character
{
public:
virtual std::string_view GetClassName() const = 0;
};
class Warrior : public Character
{
std::string_view GetClassName() const override { return "Warrior"; }
}
Did you notice the change?
A word of caution
std::string gets implicitly converted into std::string_view however, the reverse doesn’t apply.
A std::string_view does not implicitly convert back into a std::string.
Consider the following
#include <iostream>
// Accepts std::string
void print(std::string str) {
std::cout << str;
}
int main() {
std::string_view c1 = "Hello";
print(c1);
}
// Output
error: could not convert 'c1' from 'std::string_view'
There are 2 solutions
- Construct a
std::stringfrom thestd::string_viewand pass that in - Apply
static_cast<>
// Applying solution 1
std::string d1 { c1 };
print(d1);
// Applying solution 2
print(static_cast<std::string>(c1));
NOTE:
std::string_viewdoes not implicitly convert intostd::string❗
std::string_view provides read-only access
Consider this program,
#include <string>
#include <string_view>
std::string_view getName()
{
std::string name { "New York Yankees" };
return name; // Return std::string
}
The function creates and returns a temporary std::string. When the function goes out of scope, std::string_view is looking at invalid data. A dangling view has been created.
However, returning a view to a C-style string literal is safe, as seen in GetClassName() above.
NOTE: If the string that std::string_view is viewing changes then std::string_view becomes obsolete. This results in a dangling view
Advantage of std::string_view
It supports constexpr. This allows us to perform compile-time programming which is a massive plus!
E.g. constexpr std::string_view s{ "Hello beautiful world!" };
NOTE: std::string gained constexpr support as of C++20
Takeaway
std::string_view is not a direct replacement for std::string. They each serve their own purposes.
Use std::string when you need to own or modify the text.
Use std::string_view when you only need to read text owned by something else.