'understand the different construction of a std::string_view
The string_view family of template specializations provides an efficient way to pass a read-only, exception-safe, non-owning handle to the character data of any string-like objects with the first element of the sequence at position zero.
#include <iostream>
#include <string_view>
#include <unordered_map>
using namespace std;
std::unordered_map<std::string_view, int> create_map()
{
std::unordered_map<std::string_view, int> umap;
std::string s1("s1");
auto s2_bad = new std::string("s2");
umap.emplace(std::make_pair(s1, 1)); // doesn't work b/c sv points to local variable
umap.emplace(std::make_pair(*s2_bad, 2)); // Q1> why doesn't this work?
umap.emplace(std::make_pair("s3", 3)); // Q2> why does this work?
auto s4_bad = new std::string("s4_bad");
umap.emplace(std::make_pair(s4_bad->c_str(), 4)); // this works
return umap;
}
int main()
{
auto abc_map = create_map();
for(const auto&[key, value]: abc_map)
{
std::cout << "key: " << key << std::endl;
std::cout << "value: " << value << std::endl;
}
return 0;
}
Output:
key: s3
value: 3
key: $
value: 2
key: s4_bad
value: 4
key: $
value: 1
Question 1> Why doesn't s2_bad work here? Even if it points to an allocated address space.
Question 2> Why does the insertion of string literal "s3" work here? Even if it is defined within a scope of a function?
Solution 1:[1]
Question 1: std::make_pair(*s2_bad, 2) will create a std::pair<std::string, int>, so the pair has a distinct temporary std::string, unrelated to the string s2_bad points to. Then, a std::string_view will be constructed from this temporary, which will be promptly destroyed. So the moment umap.emplace(std::make_pair(*s2_bad, 2)); finishes, the string_view is invalid. If you'd like to avoid this copy (and the associated lifetime problems), you can use std::ref(*s2_bad) instead of *s2_bad.
Question 2: String literals have static lifetimes, i.e. their contents are stored in the read-only sections of binaries instead of in the stack, so holding a pointer to a string literal and returning from the function containing the string literal does not pose any dangling pointer problems.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 |
