C++17stladvanced
std::string_view
C++17 · Practical Modern · Compiler flag: -std=c++17
Explanation
A lightweight, non-owning reference to a contiguous sequence of characters. It avoids copying strings when you only need read access, dramatically improving performance in parsing, logging, and any function that accepts string-like input.
Real-World Scenario
Parse HTTP headers without allocating copies of each header name and value.
Quick Snippet
snippet.cpp
#include <string_view>
#include <iostream>
void greet(std::string_view name) {
std::cout << "Hello, " << name << "!\n";
}
greet("world"); // no allocation
std::string s = "Alice";
greet(s); // no copy
greet(std::string_view(s).substr(0, 3)); // "Ali", zero-copy substringFull Example
string_view.cpp
// CodeNebula - C++17 Example: std::string_view
// Compile: g++ -std=c++17 -Wall -Wextra -o example string_view.cpp
// Demonstrates std::string_view, a lightweight non-owning reference to a
// contiguous character sequence. It avoids copies when you only need to read
// a string, and works with std::string, C-strings, and substrings.
#include <iostream>
#include <string>
#include <string_view>
#include <vector>
#include <algorithm>
// ------------------------------------------------------------------
// 1. Function taking string_view: accepts string, char*, literals
// ------------------------------------------------------------------
void greet(std::string_view name) {
std::cout << " Hello, " << name << "! (length=" << name.size() << ")" << std::endl;
}
// ------------------------------------------------------------------
// 2. Efficient substring without copying
// ------------------------------------------------------------------
std::string_view extract_filename(std::string_view path) {
auto pos = path.find_last_of('/');
if (pos == std::string_view::npos) pos = path.find_last_of('\\');
return (pos != std::string_view::npos) ? path.substr(pos + 1) : path;
}
// ------------------------------------------------------------------
// 3. Tokenizer using string_view (zero allocations)
// ------------------------------------------------------------------
std::vector<std::string_view> split(std::string_view str, char delim) {
std::vector<std::string_view> tokens;
std::size_t start = 0;
while (start < str.size()) {
auto end = str.find(delim, start);
if (end == std::string_view::npos) end = str.size();
if (end > start) {
tokens.push_back(str.substr(start, end - start));
}
start = end + 1;
}
return tokens;
}
int main()
{
// 1. Accepting different string types without overloads
std::cout << "=== string_view as parameter ===" << std::endl;
std::string s = "Alice";
const char* cs = "Bob";
greet(s); // from std::string
greet(cs); // from const char*
greet("Charlie"); // from string literal
// 2. Non-owning substring
std::cout << "\n=== substring (no copy) ===" << std::endl;
std::string_view path = "/home/user/documents/report.pdf";
auto filename = extract_filename(path);
std::cout << " path: " << path << std::endl;
std::cout << " file: " << filename << std::endl;
// 3. Member functions
std::cout << "\n=== member functions ===" << std::endl;
std::string_view sv = " Hello, World! ";
std::cout << " original : [" << sv << "]" << std::endl;
sv.remove_prefix(2); // remove leading spaces
sv.remove_suffix(2); // remove trailing spaces
std::cout << " trimmed : [" << sv << "]" << std::endl;
std::cout << " front : '" << sv.front() << "'" << std::endl;
std::cout << " back : '" << sv.back() << "'" << std::endl;
std::cout << " substr(0,5): " << sv.substr(0, 5) << std::endl;
// 4. Searching
std::cout << "\n=== searching ===" << std::endl;
std::string_view text = "The quick brown fox jumps over the lazy dog";
std::cout << " text: " << text << std::endl;
std::cout << " find(\"fox\") : position " << text.find("fox") << std::endl;
std::cout << " find(\"cat\") : "
<< (text.find("cat") == std::string_view::npos ? "not found" : "found")
<< std::endl;
std::cout << " starts_with? : " << (text.substr(0, 3) == "The") << std::endl;
// 5. Zero-copy tokenization
std::cout << "\n=== split (zero-copy) ===" << std::endl;
std::string_view csv = "apple,banana,cherry,date";
auto tokens = split(csv, ',');
for (auto t : tokens) {
std::cout << " [" << t << "]" << std::endl;
}
// 6. Comparison with string
std::cout << "\n=== comparison ===" << std::endl;
std::string str = "hello";
std::string_view view = str;
std::cout << " str == view: " << std::boolalpha << (str == view) << std::endl;
std::cout << " view == \"hello\": " << (view == "hello") << std::endl;
return 0;
}
/*
Expected output:
=== string_view as parameter ===
Hello, Alice! (length=5)
Hello, Bob! (length=3)
Hello, Charlie! (length=7)
=== substring (no copy) ===
path: /home/user/documents/report.pdf
file: report.pdf
=== member functions ===
original : [ Hello, World! ]
trimmed : [Hello, World!]
front : 'H'
back : '!'
substr(0,5): Hello
=== searching ===
text: The quick brown fox jumps over the lazy dog
find("fox") : position 16
find("cat") : not found
starts_with? : 1
=== split (zero-copy) ===
[apple]
[banana]
[cherry]
[date]
=== comparison ===
str == view: true
view == "hello": true
*/
Run command
g++ -std=c++17 -Wall -Wextra -o example string_view.cpp