https://www.learncpp.com/cpp-tutorial/introduction-to-stdstring/
std::string
- can have flexible length, involves malloc, slower
- passing
std::string by value causes a copy, so don’t
- use
std::string_view or const std::string& as parameter
- supports
move semantics, return std::string by value is fine
- doesn’t work well with
constexpr (use string_view) instead
1
2
3
4
5
6
7
8
9
10
11
|
#include <iostream>
#include <string>
int main()
{
std::string name { "Alex" }; // initialize name with string literal "Alex"
name = "Jason"; // change name to a longer string
name = "Jay"; // change name to a shorter string
size_t l = name.length(); // get length
return 0;
}
|
string literal
1
2
3
4
5
6
7
8
9
10
11
12
13
|
int main()
{
using namespace std::string_literals; // access the s suffix
using namespace std::string_view_literals; // access the sv suffix
std::cout << "foo"; // null terminated c style string literal
std::cout << "bar"s; // std::string literal (with the suffix 's')
std::cout << "zaa"sv; // std::string_view literal (with the suffix 'sv')
// std::string literal is equivalant to
auto s = std::string {"bar", 3} ;
return 0;
}
|
std::string_view (c++17)
- basically the rust slice
- provides read-only access to existing string (or another
string_view)
- no copy
string_view parameter can take a std::string (implicit conversion), no
copy
- do not return a
string_view if created from a local string
- not vice versa:
std::string_view doesn’t implicitly convert to std::string
- can create a
std::string with a std::string_view initializer or
static_cast a string_view to string
- fully supports
constexpr
- prefer to use
constexpr std::string_view for string symbolic constants
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
#include <iostream>
#include <string>
#include <string_view>
int main()
{
// initialize with C-style string literal
std::string_view s1 { "Hello, world!" };
// initialize with std::string
std::string s{ "Hello, world!" };
std::string_view s2 { s };
// initialize with std::string_view
std::string_view s3 { s2 };
return 0;
}
|
string_view lifetime
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
|
#include <iostream>
#include <string>
#include <string_view>
int main()
{
std::string_view sv{};
{
std::string s{ "Hello, world!" };
sv = s; // sv is now viewing s
} // s is destroyed here, so sv is now viewing an invalid string
std::cout << sv << '\n'; // undefined behavior
return 0;
}
int main2()
{
std::string s { "Hello, world!" };
// sv views s
std::string_view sv { s };
// modifies s, which invalidates sv (s is still valid)
s = "Hello, universe!";
// Viewing through sv is UB here
// revalidate sv
sv = s;
// viewing through sv is valid here.
return 0;
}
|
- do not initialize
std::string_view from std::string literal => dangling
string_view