मुझे आज यह सरल कोड मिला।

#include <iostream>
#include <string>
#include <string_view>
#include <unordered_map>
#include <vector>

int main(int argc, char* argv[]) {
  std::unordered_map<std::string, int> m = {
      {"asdf", 123},
      {"dsdfesjfdaslkfjasljlasfjlasjfakdlsfjasklfajsklfjaskljlf", 123},
      {"ldfjaslk}sfjalskdfjlkdasjfaslkfjaskdljflaskdfjdaslkfjasdlkfjasdlj", 1},
      {"ldafjaslk}sfjalskdfjlkdasjfaslkfjaskdljflaskdfjdaslkfjasdlkfjasdlj", 1},
      {"ldjaksdfjfjaslk}sfjalskdfjlkdasjfaslkfjaskdljflaskdfjdaslkfjasdlkfjasdlj", 1},
      {"ldfjaslk}sfdasfdsfjalskdfjlkdasjfaslkfjaskdljflaskdfjdaslkfjasdlkfjasdlj", 1},
      {"ldfjaslk}sfjalsksfdasdfdfjlkdasjfaslkfjaskdljflaskdfjdaslkfjasdlkfjasdlj", 1},
      {"ldfjaslk}sfjalskdfjlkdasjfaslkfjaskdljflaskdfjdaslkfjasdlkfjasdlj", 1},
  };

  std::vector<std::pair<std::string_view, int>> vec;

  for (auto& [s, i] : m) {
    vec.push_back(std::make_pair(s, i));
    std::cout << vec.back().first << std::endl;
  }
}

मूल रूप से, वेक्टर मानचित्र के तत्व के साथ बनाया गया है। बात यह है कि वेक्टर में डालने पर यह स्ट्रिंग को string_view में परिवर्तित कर देता है। मैंने सोचा कि यह ठीक रहेगा क्योंकि हम string_view बनाने के लिए कॉन्स्ट स्ट्रिंग संदर्भ का उपयोग कर रहे हैं, और स्ट्रिंग वेक्टर के पूरे जीवनकाल में उपलब्ध होगी।

लेकिन जब मैंने आउटपुट की जाँच की, तो यह प्रतीत होता है कि दूषित डेटा दिखा।

�/�U.�Usfdasdfdfjlkdasjfaslkfjaskdljflaskdfjdaslkfjasdlkfjasdlj
�/�U.�Usfjalskdfjlkdasjfaslkfjaskdljflaskdfjdaslkfjasdlkfjasdlj
@/�U.�Ukdfjlkdasjfaslkfjaskdljflaskdfjdaslkfjasdlkfjasdlj
�/�U.�Usfjalskdfjlkdasjfaslkfjaskdljflaskdfjdaslkfjasdlkfjasdlj
@/�U.�Udfjlkdasjfaslkfjaskdljflaskdfjdaslkfjasdlkfjasdlj
.�Usljlasfjlasjfakdlsfjasklfajsklfjaskljlf
asdf

मुझे लगता है कि वेक्टर में string_view अब उचित तत्व को इंगित नहीं करता है। लेकिन ऐसा क्यों हुआ है? मुझे लगता है कि unordered_map पुनरावृत्ति करते समय अपरिवर्तनीय होगा, इसलिए मुख्य तत्व का पता नहीं बदला होगा।

गॉडबोल्ट लिंक : https://godbolt.org/z/dePdv5

c++
2
Jaebum 20 पद 2020, 15:14
 – 
Jaebum
20 पद 2020, 15:22
1
क्या std::make_pair स्ट्रिंग की प्रतिलिपि नहीं बनाएंगे, और फिर vec प्रतिलिपि के संदर्भ को संग्रहीत नहीं करेंगे?
 – 
spectras
20 पद 2020, 15:22
आह। इसलिए जब मैंने इसे vec.push_back(std::make_pair(std::string_view(s), i)); पर ठीक किया, तो इसने इसे ठीक कर दिया। लेकिन मुझे आश्चर्य है कि यह एक डिफ़ॉल्ट व्यवहार कैसे नहीं होगा?
 – 
Jaebum
20 पद 2020, 15:24
2
यह emplace_back के साथ और make_pair के बिना बेहतर काम करता है: लाइव कोलिरू पर डेमो ;-)
 – 
Scheff's Cat
20 पद 2020, 15:25

1 उत्तर

सबसे बढ़िया उत्तर

make_pair का उपयोग करके आप std::pair<std::string, int> प्रकार की एक अस्थायी वस्तु उत्पन्न करते हैं। मैं एक त्रुटि फेंकने के लिए std::pair<std::string_view, int> में रूपांतरण की अपेक्षा करता हूं, लेकिन स्पष्ट रूप से यह काम करता है।

किसी भी तरह, std::string_view गैर-स्वामित्व वाला है, इसलिए जैसे ही अस्थायी वस्तु नष्ट हो जाती है (पंक्ति ; के अंत में) यह लटकती हो जाती है।

आपको नई जोड़ी नहीं बनानी चाहिए। emplace_back कुंजी और मान के साथ प्रयास करें।

3
JHBonarius 20 पद 2020, 15:28
ठंडा। मुझे emplace_back से बचने के लिए कहा गया है क्योंकि यह अनपेक्षित ctor कह सकता है। लेकिन मुझे लगता है कि यह एकमात्र मामला है जो मुझे उपयोगी लगता है: पी
 – 
Jaebum
20 पद 2020, 15:28
2
रूपांतरण मौजूद है क्योंकि std::string से std::string_view एक अंतर्निहित रूपांतरण है। आप देखते हैं कि लोग उस निर्णय के बारे में "परेशान" क्यों थे।
 – 
Passer By
20 पद 2020, 15:35
गंभीरता से? मुझे लगता है कि मैं अब "अपसेट क्लब" में शामिल हो रहा हूं।
 – 
JHBonarius
20 पद 2020, 16:06