Step 3 of 7
std::string_view
A function that only reads a string often takes const std::string&. That works, but when a caller passes a literal like "hello", a temporary std::string must be built first, copying the characters (and allocating heap memory if the text is long). And taking a piece of a string with substr makes yet another copy.
std::string_view (from <string_view>) is a lightweight view: just a pointer to some characters and a length. It never owns or copies the text. It accepts literals, std::strings and parts of either for free.
#include <iostream>
#include <string>
#include <string_view>
std::string_view file_extension(std::string_view path) {
auto dot = path.rfind('.');
if (dot == std::string_view::npos) return {}; // empty view
return path.substr(dot + 1); // a view into path: no copy
}
int count_char(std::string_view s, char c) {
int n = 0;
for (char x : s) n += (x == c);
return n;
}
int main() {
std::cout << file_extension("report.final.pdf") << "\n";
std::string name = "photo.jpeg";
std::cout << file_extension(name) << "\n";
std::cout << "[" << file_extension("README") << "]\n";
std::string_view v = " banana ";
v.remove_prefix(2); // just moves the start
std::cout << count_char(v, 'a') << " " << v.size() << " " << v.starts_with("ban") << "\n";
}
pdf
jpeg
[]
3 8 1
How it works
substr,remove_prefixandremove_suffixon a view only adjust its pointer and length. Nothing is copied, so they're O(1).- A view has most of
std::string's read-only interface:size,[],find,rfind,starts_with,ends_with,substr, and range-for. - Take
std::string_viewby value. It's just a pointer and a length, so copying it is as cheap as passing a reference.
The danger: views don't keep text alive
A view points at characters owned by someone else. If the owner dies, the view dangles:
std::string_view bad() {
std::string s = "temporary";
return s; // s is destroyed here; the view points at freed memory
}
Rule of thumb: use string_view for parameters; return it only when it points into something the caller owns, like file_extension does.
Your task: trim
Move the start past leading spaces with remove_prefix(1) while the first character is ' ', then do the same at the end with remove_suffix(1) and back(). Check empty() first each time so an all-spaces string ends up as an empty view.
Your turn: write std::string_view trim(std::string_view s) that returns the view without leading and trailing spaces.