2016-09-19 7 views
10

मैं std::string_view का उपयोग करने के लिए प्रेरणा को समझता हूं;
यह फ़ंक्शन तर्कों में अनावश्यक आवंटन से बचने में मदद कर सकता है।मैं std :: string_view के बजाय कॉन्स्ट और std :: स्ट्रिंग कब पास करूंगा?

उदाहरण के लिए:
निम्नलिखित कार्यक्रम एक स्ट्रिंग शाब्दिक से एक std::string पैदा करेगा।
यह एक अवांछित गतिशील आवंटन का कारण बनता है, क्योंकि हम केवल पात्रों को देखने में रूचि रखते हैं।

#include <iostream> 

void* operator new(std::size_t n) 
{ 
    std::cout << "[allocating " << n << " bytes]\n"; 
    return malloc(n); 
} 

void observe_string(std::string const& str){} 

int main(){ 
    observe_string("hello world"); //prints [allocating 36 bytes] 
} 

string_view का उपयोग करते हुए समस्या का समाधान होगा:

#include <iostream> 
#include <experimental/string_view> 

void* operator new(std::size_t n) 
{ 
    std::cout << "[allocating " << n << " bytes]\n"; 
    return malloc(n); 
} 

void observe_string(std::experimental::string_view const& str){ 
} 

int main(){ 
    observe_string("hello world"); //prints nothing 
} 

यह एक प्रश्न के साथ मुझे छोड़ देता है।
फ़ंक्शन तर्कों के लिए string_view के बजाय मैं std :: स्ट्रिंग को const & द्वारा कब चुनूं?

std::string_view के इंटरफेस को देखते हुए, यह लगता है जैसे कि मैं std::string की सभी आवृत्तियों कि const& द्वारा पारित कर रहे हैं बदल सकते थे। क्या इसके लिए कोई काउंटर उदाहरण हैं? std::string_view पैरामीटर पास करने के लिए std::string const& को प्रतिस्थापित करने के लिए है?

+0

मैं यह कहने जा रहा था: यदि फ़ंक्शन पैरामीटर को एक अलग std :: स्ट्रिंग में आंतरिक रूप से छीनने जा रहा था, तो प्रति-निर्माण स्ट्रिंग-टू-स्ट्रिंग-व्यू-टू-स्ट्रिंग राउंड-ट्रिप से सस्ता होगा । लेकिन मुझे एहसास हुआ कि basic_string_view याद रख सकता है कि इसे एक स्ट्रिंग से बनाया गया था, और केवल उसी को अपनी to_string() विधि से वापस कर दें। –

+0

@SamVarshavchik: यदि आप एक प्रतिलिपि बनाने जा रहे हैं, तो आप तर्क के आधार पर तर्क स्वीकार करना चाहते हैं ताकि यह या तो प्रतिलिपि हो या स्थानांतरित हो सके। – GManNickG

उत्तर

2

आंद्रेई अलेक्जेंड्रेसकू ने एक बार कहा, "कुछ काम से कोई काम बेहतर नहीं है"। तो आपको ऐसे संदर्भों में const std::string& का उपयोग करना चाहिए। क्योंकि std::string_view में अभी भी कुछ काम शामिल है (पॉइंटर और लंबाई की एक जोड़ी कॉपी करना)।

बेशक, कॉन्स संदर्भों में अभी भी एक सूचक की प्रतिलिपि बनाने की लागत हो सकती है; जो std::string_view के बराबर है। लेकिन std::string_view के साथ एक अतिरिक्त काम है, यह लंबाई की प्रतिलिपि बनाता है।

इस सिद्धांत में है, लेकिन व्यवहार में, एक बेंचमार्क प्रदर्शन अनुमान लगाने के लिए


+0

@ एम.एम. मान लीजिए कि हम प्रत्येक रिकर्सन में एक ही टुकड़ा नहीं देख रहे हैं? – WhiZTiM

+0

@ एमएम, मैंने रिकर्सन उदाहरण हटा दिया है, यह वास्तव में स्ट्रिंग_व्यू के पक्ष में है जो ओपी का सवाल नहीं है। – WhiZTiM

+4

यदि फ़ंक्शन को स्ट्रिंग अक्षर के साथ बुलाया जाता है, तो 'const string &' संस्करण अधिक काम करेगा। – juanchopanza

5

जब मैं std::string समारोह तर्क के लिए const& बजाय string_view द्वारा चुनेंगे को प्राथमिकता दी जाएगी?

क्या आप एक शून्य-समाप्त स्ट्रिंग की आवश्यकता है? यदि ऐसा है, तो आपको std::string const& का उपयोग करना चाहिए जो आपको गारंटी देता है। string_view नहीं - यह बस const char की एक श्रृंखला है।

आप एक अशक्त-समाप्त स्ट्रिंग की जरूरत है नहीं , और आप डेटा का स्वामित्व लेने की जरूरत नहीं है, तो आप string_view उपयोग करना चाहिए। यदि आपको डेटा का स्वामित्व लेने की आवश्यकता है, तो यह मामला हो सकता है कि string मूल्य से string_view से बेहतर है।

+2

स्पष्टीकरण के लिए: मेरी स्ट्रिंग नल-टर्मिनेटेड की आवश्यकता है जिसका अर्थ है 'std :: string' अंतर्निहित 'char'-array' \ 0' में समाप्त होना चाहिए, है ना? कल्पना करना मुश्किल है कि पहले से ही 'std :: string' का उपयोग करते समय किसी को इसकी आवश्यकता है। यह आधुनिक सी ++ के साथ मिश्रण सी की तरह है, या मैं गलत हूँ? –

+0

अगर किसी को एनटीबीएस की आवश्यकता है, तो मुझे लगता है कि वे पैरामीटर प्रकार के रूप में 'कॉन्स्ट char *' का उपयोग कर सकते हैं। – cpplearner

+0

@ एम। विंटर यह कल्पना करना बहुत आसान है ... बहुत सारे एपीआई हैं जिन्हें शून्य-समाप्त तारों की आवश्यकता होती है। – Barry

2

string_view के बजाय const std::string& को स्वीकार करने का एक संभावित कारण यह है कि जब आप स्ट्रिंग ऑब्जेक्ट के संदर्भ को संग्रहीत करना चाहते हैं जो बाद में बदल सकता है।

यदि आप string_view स्वीकार करते हैं और स्टोर करते हैं, तो string आंतरिक बफर पुन: आवंटित होने पर यह अमान्य हो सकता है।

यदि आप स्वयं स्ट्रिंग के संदर्भ को स्वीकार करते हैं और संग्रहीत करते हैं, तो आपको तब तक समस्या नहीं होगी, जब तक कि ऑब्जेक्ट जीवित न हो (आप शायद अस्थायी के साथ स्पष्ट समस्या से बचने के लिए आर-वैल्यू संदर्भ अधिभार को हटाना चाहते हैं)।

संबंधित मुद्दे