Home > OS >  understand the different construction of a std::string_view
understand the different construction of a std::string_view

Time:04-07

Live On Coliru

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?

CodePudding user response:

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.

  •  Tags:  
  • c
  • Related