विषय पर बढ़ें

अंतिम अद्यतन:2026-10-12

C++17 std::string_view

0. समस्या

string_view C++17 के बाद आया, यह असल में leveldb का slice ही है, इसका उद्देश्य मेमोरी कॉपी की समस्या हल करना और कुशल substr प्रदान करना है।

लेकिन, इससे पॉइंटर और रेफ़रेंस की समस्या भी आती है, क्योंकि string_view इंगित की गई सामग्री का स्वामित्व नहीं रखता, Rust से तुलना करें तो यह केवल उधार लेना (borrow) है, यदि सामग्री रखने वाला ऑब्जेक्ट पहले ही रिलीज़ हो जाए, तो dangling reference की समस्या आ जाती है। Rust की तरह, कंपाइल के समय वेरिएबल के जीवनचक्र का विश्लेषण होता है, जिससे यह सुनिश्चित होता है कि उधार लिया संसाधन उपयोग के समय तक रिलीज़ न हो। लेकिन C++ में कोई जाँच नहीं है, इसे मैन्युअल रूप से सुनिश्चित करना पड़ता है।

1. आंतरिक क्रियान्वयन

string_view एक basic_string_view प्रकार है, देखा जा सकता है कि _Traits डिफ़ॉल्ट रूप से char_traits अपनाता है, यह बहुत महत्वपूर्ण है, आगे के कुछ फ़ंक्शन char_traits के कुछ मेंबर फ़ंक्शनों से ही मुख्य ऑपरेशन निष्पादित करते हैं।

template<class _CharT, class _Traits = char_traits<_CharT> >
    class _LIBCPP_TEMPLATE_VIS basic_string_view;

typedef basic_string_view<char>     string_view;

basic_string_view के आंतरिक मेंबर:

private:
    const   value_type* __data;
    size_type           __size;

कंस्ट्रक्टर string और const char* के साथ संगत

constexpr basic_string_view() noexcept;
constexpr basic_string_view(const basic_string_view&) noexcept = default;
basic_string_view& operator=(const basic_string_view&) noexcept = default;
template<class Allocator>
constexpr basic_string_view(const charT* str);
constexpr basic_string_view(const charT* str, size_type len);

इटरेटर समर्थन:

constexpr const_iterator begin() const noexcept;
constexpr const_iterator end() const noexcept;
constexpr const_iterator cbegin() const noexcept;
constexpr const_iterator cend() const noexcept;
const_reverse_iterator rbegin() const noexcept;
const_reverse_iterator rend() const noexcept;
const_reverse_iterator crbegin() const noexcept;
const_reverse_iterator crend() const noexcept;

अन्य मुख्य फ़ंक्शन:

  • substr
  • remove_prefix
  • compare
  • find
  • ...

c++20 से starts_with, ends_with, contains का समर्थन है, ये तीनों leveldb के slice में शुरू से ही थे।

char* के लिए string_view लिटरल:

constexpr basic_string_view<char>     operator "" sv( const char *str,     size_t len ) noexcept;
constexpr basic_string_view<wchar_t>  operator "" sv( const wchar_t *str,  size_t len ) noexcept;
constexpr basic_string_view<char16_t> operator "" sv( const char16_t *str, size_t len ) noexcept;
constexpr basic_string_view<char32_t> operator "" sv( const char32_t *str, size_t len ) noexcept;

2. उपयोग के जाल

2.1 \0

string_view को \0 की चिंता नहीं होती, यह वास्तविक कैरेक्टर संख्या को देखता है।

std::string_view s = "abc\0\0def"sv;
std::cout << "s: " << s.size() << " \"" << s << "\"\n";

आउटपुट: s: 8 "abcdef"

std::string_view str{"hello", 1};
std::cout << str.data() << std::endl; // 输出 hello,而不是h

यहाँ अपेक्षित आउटपुट hello था, लेकिन h आया।

2.2 जीवनचक्र

string_view foo() {
    std::string s{"hello world"};
    return string_view{s};
}

इस उदाहरण में, s scope से बाहर हो गया, और string_view dangling reference बन गया।

जीवनचक्र

std::string_view अंतर्निहित कैरेक्टर संग्रह का स्वामी नहीं है, ज़रूर सुनिश्चित करें कि संदर्भित ऑब्जेक्ट का जीवनचक्र पूरे उपयोग अवधि को कवर करे।

संबंधित विषय

टिप्पणियाँ