2011-01-19 13 views
8

इतने लंबे प्रश्न के लिए खेद है, लेकिन मैं जितना संभव हो उतना स्पष्ट होने की कोशिश करता हूं। यह किसी भी तरह से मेरे पिछले प्रश्न strings in C++ के बारे में बताता है। मैं यह पता लगाने की कोशिश कर रहा हूं कि मैं एनआरवीओ पर भरोसा किए बिना अनावश्यक स्मृति आवंटन, के बिना किसी फ़ंक्शन से std :: स्ट्रिंग कैसे वापस कर सकता हूं। कारण मैं NRVO पर भरोसा नहीं करना चाहते हैं:एसटीएल वापसी पर स्वैप?

  • यह संकलक हम वर्तमान में भी जब यह समर्थित है यह हमेशा डीबग मोड में सक्षम नहीं किया जा सकता है
  • का उपयोग द्वारा समर्थित नहीं है
  • यह कुछ मामलों (example) में विफल हो सकता है

कृपया ध्यान दें कि मैं एक सी ++ 03 संगत समाधान की जरूरत है (कोई C++ 0x rvalue संदर्भ इस प्रकार, दुर्भाग्य से ...)

si mplest तरीका यह है है पारित-दर-संदर्भ और इस

void test(std::string& res) 
{ 
    std::string s; 
    //... 
    res.swap(s); 
} 

की तरह, std :: स्वैप करना लेकिन यह से संदर्भ से गुजरती हैं, मैं इतना क्या हासिल करना चाहते मूल्य से वापस जाने के लिए और अधिक प्राकृतिक और अक्सर अधिक सुविधाजनक है यह है:

std::string test() 
{ 
    std::string s; 
    //... 
    return SOMETHING(s); 
} 

आदर्श रूप में यह सिर्फ एक swap "वापसी मान" के साथ क्या करना होगा, लेकिन मैं कैसे सी में यह करने के लिए ++ दिखाई नहीं देता। Auto_ptr पहले से ही कॉपी की बजाय आगे बढ़ता है, और मैं वास्तव में auto_ptr<string> का उपयोग कर सकता हूं, लेकिन मैं स्ट्रिंग ऑब्जेक्ट को गतिशील रूप से आवंटित करना चाहता हूं।

मेरा विचार किसी स्ट्रिंग ऑब्जेक्ट को "टैग" करना है कि इसे पर जाने के लिए किसी फ़ंक्शन से वापस लौटाया जा रहा है जब प्रतिलिपि प्रतिलिपि को वापस लौटाया जाता है। इसलिए मैं इस कोड के साथ समाप्त हो गया है, जो वास्तव में करता है जो मैं चाहता:

struct Str 
{ 
    struct Moveable 
    { 
     Str & ref; 
     explicit Moveable(Str & other): ref(other) {} 
    }; 

    Str() {} 
    Str(const std::string& other) : data(other) {} // copy 
    Str(Moveable& other) { data.swap(other.ref.data); } // move 

    Moveable Move() 
    { 
     return Moveable(*this); 
    } 

    std::string data; 
}; 

Str test() 
{ 
    Str s; 
    //... 
    return s.Move(); // no allocation, even without NRVO 
} 

तो ... है यह सब कर भावना, या वहाँ कुछ गंभीर मुद्दों है कि मैं याद कर रहा हूँ कर रहे हैं? (मुझे यकीन नहीं है कि उदाहरण के लिए कोई आजीवन समस्या नहीं है)। हो सकता है कि आपने पहले से ही इस तरह के विचार को पुस्तकालय (पुस्तक, आलेख ...) में देखा है, और मुझे इसका संदर्भ दे सकता है?

संपादित करें: जैसा कि @ रेस्टवेन्स ने देखा है, यह कोड एमएसवीसी-विशिष्ट है और जी ++ के तहत संकलित नहीं होगा जो गैर-कॉन्स अस्थायी पसंद नहीं करता है। यह एक समस्या है, लेकिन आइए मान लें कि यह कार्यान्वयन एमएसवीसी-विशिष्ट है।

+0

मुझे यकीन है कि आप क्या पूछ रहे हैं। क्या आपको बस अपना कोड ठीक करने की ज़रूरत है? आप कहते हैं कि यह वही करता है जो आप चाहते हैं लेकिन - जहां तक ​​मैं देख सकता हूं - इसे संकलित नहीं करना चाहिए। –

+2

क्या आपने जांच की है कि आपकी स्ट्रिंग गाय करता है या नहीं। यदि ऐसा है तो कुछ अतिरिक्त स्मृति आवंटन होंगे। इसके अलावा std :: स्ट्रिंग के कुछ कार्यान्वयन ऑब्जेक्ट में स्ट्रिंग को रखेंगे (जब स्ट्रिंग कम हो) इसके बजाय स्मृति आवंटित करने के बजाय। यदि इनमें से कोई भी सत्य है तो ऑप्टिमाइज़ेशन पर आपके प्रयासों को कम करने के बजाय लागत में वृद्धि हो सकती है। –

+0

@ चार्ल्स: कोड यह समझाने के लिए है कि मैं क्या हासिल करने की कोशिश कर रहा हूं, और सवाल यह है कि यदि मैं इसे सही देखता हूं और यदि पहले से ही कुछ अच्छे कार्यान्वयन हैं। –

उत्तर

4

बूस्ट उपयोगों के कार्यान्वयन Boost.Thread जैसे पुस्तकालयों के लिए आंतरिक रूप से अर्थशास्त्र अनुकरण को स्थानांतरित करते हैं। आप कार्यान्वयन को देखना और कुछ ऐसा करना चाहते हैं।

संपादित करें: वास्तव में लाइब्रेरी Boost.Move लाइब्रेरी का सक्रिय विकास है, इसलिए आप इसे पहले से ही उपयोग करना शुरू कर सकते हैं।

0

क्या आपने वास्तव में यह निर्धारित किया है कि मूल्य द्वारा लौटने से आपके आवेदन में एक प्रदर्शन समस्या है? यह जाने का सबसे आसान/आसान तरीका लगता है, और जब आप एक और आधुनिक कंपाइलर में अपग्रेड करते हैं तो आप रावल संदर्भों का उपयोग कर सकते हैं।

मैं s के विनाश आदेश के संबंध में Movable के संदर्भ के प्रश्न के उत्तर का उत्तर नहीं दे सकता। आप अपने कंपाइलर के लिए, ऑर्डर करने के लिए विभिन्न रचनाकारों और विनाशकों में कोड डाल सकते हैं।भले ही यह ठीक दिखता है, फिर भी मैं आपके द्वारा उल्लिखित सामान्य पैटर्नों में से एक का उपयोग करने पर विचार करता हूं, हालांकि पाठक भ्रम को रोकने और संभवतः वैकल्पिक कंपाइलर को तोड़ने के लिए।

+1

यह केवल मेरे लिए अनुकूलन का सवाल नहीं है, क्योंकि यह सामान्य उपयोग को प्रभावित करता है - जब तक डेवलपर्स को पता न हो कि मूल्य से वापसी सस्ता है, तो वे ऐसा करने से बचने की कोशिश करेंगे। लोग अभी भी कुछ इष्टतम कोड लिखने का प्रयास करते हैं, भले ही आप कहते हैं कि समयपूर्व अनुकूलन बुरा है। –

1

क्या आपने यह कोड g ++ पर देखा है?

चूंकि आप एक अस्थायी वस्तु (जिसे s.Move() द्वारा लौटाया गया है) के साथ स्ट्र (मूवबल &) कहते हैं!

यह मानक का अनुपालन नहीं है और g ++ द्वारा समर्थित नहीं है। यह एमएसवीसी द्वारा समर्थित है! (एमएस इसे एक सुविधा कहते हैं ...)।

+0

आप सही हैं, g ++ के तहत संकलित नहीं होंगे, मैंने प्रश्न अपडेट किया है। जी ++ के लिए शायद कुछ अलग किया जा सकता है, लेकिन मुझे यह जानने में अधिक दिलचस्पी है कि कुछ * समान * कहीं भी उपयोग किया जाता है, बिल्कुल मेरा नमूना कार्यान्वयन नहीं। –