2016-12-22 5 views
6

मेरे पास एक विधि है जो std::string_view लेती है और फ़ंक्शन का उपयोग करती है, जो पैरामीटर के रूप में शून्य समाप्त स्ट्रिंग लेती है। उदाहरण के लिए:एपीआई के साथ std :: string_view का उपयोग करके, शून्य समाप्त होने वाली स्ट्रिंग

void stringFunc(std::experimental::string_view str) { 
    some_c_library_func(/* Expects null terminated string */); 
} 

सवाल यह है कि, इस स्थिति को संभालने का उचित तरीका क्या है? str.to_string().c_str() एकमात्र विकल्प है? और मैं वास्तव में इस विधि में std::string_view का उपयोग करना चाहता हूं, क्योंकि मैं इसमें विभिन्न प्रकार के तारों को पास करता हूं।

उत्तर

4

आप std::string_view के माध्यम से एक तार को बदल नहीं सकते। इसलिए आप '\0' वर्ण को समाप्त नहीं कर सकते हैं। इसलिए आपको '\0' -terminator जोड़ने के लिए कहीं और स्ट्रिंग की प्रतिलिपि बनाने की आवश्यकता है। स्ट्रिंग पर स्ट्रिंग डालने से आप ढेर आवंटन से बच सकते हैं, अगर यह काफी छोटा है। यदि आप जानते हैं कि std::string_view एक नल-टर्मिनेटेड स्ट्रिंग का हिस्सा है, तो आप जांच सकते हैं कि अगर अंत में वर्ण '\0' वर्ण है और उस मामले में प्रतिलिपि से बचें। इसके अलावा, मुझे अनुकूलन के लिए और अधिक जगह नहीं दिख रही है।

+0

वीएलए के लिए अच्छा उपयोग। – user1095108

+4

@ user1095108 लेकिन कोई संकलक जो सी ++ में वीएलए को गैर-मानक एक्सटेंशन लागू कर रहा है, तो मैं कहूंगा कि वीएलए कभी भी अच्छा नहीं हो सकता है। : पी –

+0

वे व्यावहारिक रूप से एलोका के माध्यम से हर जगह समर्थित हैं, आप उन्हें पोर्टेबल – user1095108

4

आप निश्चित रूप से std::experimental::string_view पर data नहीं बुलाना चाहिए:

basic_string :: डेटा के विपरीत() और स्ट्रिंग शाब्दिक, डेटा() एक बफर कि अशक्त-समाप्त नहीं है करने के लिए एक सूचक वापस आ सकते हैं।

तो उस पर to_string और data फोन:

void stringFunc(std::experimental::string_view str) { 
    some_c_library_func(str.to_string().data()); 
} 

या:

void stringFunc(std::experimental::string_view str) { 
    std::string real_str(str); 
    some_c_library_func(real_str.data()); 
} 
8

मैंने string_view कक्षा zstring_view नामक एक वैकल्पिक वैकल्पिक बनाकर इस समस्या को हल किया। इसे string_view से निजी रूप से विरासत में मिला है और इसमें इसका अधिकांश इंटरफ़ेस शामिल है।

सिद्धांत अंतर यह है कि zstring_viewstring_view से नहीं बनाया जा सकता है। इसके अलावा, string_view एपीआई जो अंत से तत्वों को हटाएंगे वे इंटरफ़ेस का हिस्सा नहीं हैं या वे zstring_view के बजाय string_view लौटाते हैं।

उन्हें किसी भी एनयूएल-समाप्त स्ट्रिंग स्रोत से बनाया जा सकता है: std::string और आगे। मैंने उनके लिए विशेष उपयोगकर्ता परिभाषित शाब्दिक प्रत्यय भी बनाया: _zsv

यह विचार यह है कि, जब तक आप गैर-एनयूएल-समाप्त स्ट्रिंग को zstring_view मैन्युअल रूप से नहीं डालते हैं, तो सभी zstring_view एस को एनयूएल-समाप्त किया जाना चाहिए। std::string की तरह, एनयूएल चरित्र स्ट्रिंग के आकार का हिस्सा नहीं है, लेकिन यह है।

मुझे सी इंटरफेसिंग से निपटने के लिए यह बहुत उपयोगी लगता है।

+0

बना सकते हैं, मैंने अभी भी ऐसा ही किया है, और मैं मानता हूं कि इंटरफ़ेस बहुत अच्छा है और कभी भी स्थिरांक std :: string और पैरामीटर के रूप में करने का अंतिम कारण हटा देता है।आप निजी विरासत (जैसे तुलना, और स्ट्रिंग_व्यू पर वापस रूपांतरण) का उपयोग करके बहुत सारी सुविधा खो देते हैं - इंटरफ़ेस को देखते हुए, ऐसा लगता है कि केवल समस्याग्रस्त म्यूटेटर _ *** फिक्स और स्वैप को हटा रहे हैं - मैंने बस स्वैप को फिर से कार्यान्वित किया है, और जोड़ा गया _ *** निजी गैर-कार्यान्वित सदस्यों के रूप में ठीक करें, और सबकुछ ठीक काम करने लगता है - इसलिए आप वास्तव में std :: string_view से सार्वजनिक रूप से प्राप्त कर सकते हैं। भविष्य में स्ट्रिंग_व्यू में केवल नए म्यूटेटर जोड़े गए हैं। – Shaggi

+0

हालांकि यह कहा जा सकता है कि यह खराब शैली है। और इसके अतिरिक्त, आपको स्ट्रिंग_व्यू लेने वाले कार्यों के लिए zstring_views को पास करने के साथ समस्याएं होंगी (और जो दो से अधिक तरीकों से अजीब है ...) – Shaggi

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

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