क्या रैवल्यू संदर्भ अधिक कुशल है?


जवाबों:


246
Beta_ab&&
Beta::toAB() const {
    return move(Beta_ab(1, 1));
}

यह एक झूलने वाला संदर्भ देता है, जैसे कि लैवल्यू संदर्भ मामले के साथ। फ़ंक्शन के वापस आने के बाद, अस्थायी ऑब्जेक्ट नष्ट हो जाएगा। आपको Beta_abनिम्नलिखित की तरह मूल्य से वापस लौटना चाहिए

Beta_ab
Beta::toAB() const {
    return Beta_ab(1, 1);
}

अब, यह Beta_abफ़ंक्शन के रिटर्न वैल्यू में एक अस्थायी ऑब्जेक्ट को ठीक से स्थानांतरित कर रहा है । यदि कंपाइलर कर सकता है, तो वह आरवीओ (रिटर्न वैल्यू ऑप्टिमाइज़ेशन) का उपयोग करके, चाल से पूरी तरह से बच जाएगा। अब, आप निम्न कार्य कर सकते हैं

Beta_ab ab = others.toAB();

और यह अस्थायी रूप से निर्माण करेगा ab, या आरवीओ को एक चाल या प्रतिलिपि पूरी तरह से करने के लिए छोड़ देगा। मैं आपको BoostCon09 Rvalue References 101 पढ़ने की सलाह देता हूं जो इस मामले की व्याख्या करता है और कैसे (N) RVO के साथ बातचीत करने के लिए होता है।


आपका रेवेले संदर्भ वापस करने का मामला अन्य अवसरों में एक अच्छा विचार होगा। कल्पना कीजिए कि आपके पास एक getAB()फ़ंक्शन है जिसे आप अक्सर एक अस्थायी पर आमंत्रित करते हैं। यह ऐसा करने के लिए इष्टतम नहीं है कि यह एक अस्थायी अंतराल के लिए एक लौटे रेवेलेरी लौटें। आप इसे इस तरह से लागू कर सकते हैं

struct Beta {
  Beta_ab ab;
  Beta_ab const& getAB() const& { return ab; }
  Beta_ab && getAB() && { return move(ab); }
};

ध्यान दें कि moveइस मामले में वैकल्पिक नहीं है, क्योंकि abन तो एक स्थानीय स्वचालित है और न ही एक अस्थायी प्रतिद्वंद्विता है। अब, रेफरी-क्वालीफायर का && कहना है कि दूसरा कार्य प्रतिद्वंद्विता के अस्थायी लोगों पर लागू किया गया है, प्रतिलिपि के बजाय निम्नलिखित कदम बना रहा है

Beta_ab ab = Beta().getAB();

51
मैंने हमेशा यह मान लिया था कि जब वापसी प्रकार एक r- मान संदर्भ था, तो लटकती संदर्भ समस्या स्वत: ही चली गई। खुशी है कि मुझे इससे पहले कि मुझे थोड़ा सा बाहर मिला। स्टैक मुंहतोड़ कीड़े चूसना।
deft_code

31
:) वास्तव में, रेवल्यू संदर्भ "जस्ट रेफरेंस" होते हैं जैसे लैवल्यू रेफरेंस होते हैं। वे कुछ भी कॉपी या स्टोर नहीं करते हैं।
जोहान्स शहाब -

9
एक साधारण कांस्टीशन से अधिक सदस्य के कार्य पर योग्यता और योग्यता क्या है?
गलिनेट


3
@galinette ये Ref- Qualifiers हैं ।
मैल्कम

2

यह अधिक कुशल हो सकता है, उदाहरण के लिए, थोड़ा अलग संदर्भ में:

template <typename T>
T&& min_(T&& a, T &&b) {
    return std::move(a < b? a: b);
}

int main() {
   const std::string s = min_(std::string("A"), std::string("B"));
   fprintf(stderr, "min: %s\n", s.c_str());
   return 0;
}

एक दिलचस्प अवलोकन के रूप में, मेरी मशीन पर clang++ -O3नियमित रूप से 62 निर्देशों के ऊपर कोड के लिए 54 निर्देश उत्पन्न होते हैं std::min। हालांकि, इसके साथ -O0नियमित रूप से 481 से ऊपर कोड के लिए 518 निर्देश उत्पन्न करता है std::min


मैं आपके उत्तर से भ्रमित हूं। एक समान (शायद) संस्करण की कोशिश की थी, लेकिन विफल रहा: ideone.com/4GyUbZ क्या आप बता सकते हैं कि क्यों?
डेकांग

आपने अस्थायी ऑब्जेक्ट पर संदर्भ का उपयोग किया for(:)और डीलॉक्लेटेड ऑब्जेक्ट पर एकीकृत किया। फिक्स: ideone.com/tQVOal
wonder.mice

3
क्या यह उत्तर वास्तव में गलत नहीं है? पैरामीटर टी, T टेम्पलेट के लिए && है नहीं एक आर मूल्य संदर्भ, बल्कि एक सार्वभौमिक संदर्भ, और कहा कि मामले के लिए, हम चाहिए हमेशा कॉल std :: आगे <टी>, नहीं std :: चाल! यह उल्लेख करने के लिए नहीं, कि यह उत्तर सीधे ऊपर-ऊपर के मतदान का खंडन करता है।
xdavidliu

@xdavidliu यह उत्तर एक विरोधाभासी उदाहरण है कि प्रतिद्वंद्विता द्वारा कैसे वापसी अधिक कुशल हो सकती है। std::move()बिंदु का अधिक स्पष्ट रूप से वर्णन करने के लिए एक स्पष्ट कलाकारों के रूप में उपयोग किया जाता है। यह ऐसा कोड नहीं है जिसे आप अपने प्रोजेक्ट में कॉपी-पेस्ट करेंगे। यह शीर्ष-मतदान जवाब का खंडन नहीं करता है, क्योंकि फ़ंक्शन के अंदर अस्थायी ऑब्जेक्ट बनाया जाता है। यहाँ लौटी वस्तु एक तर्क है (अस्थायी वस्तुओं को पूर्ण अभिव्यक्ति के मूल्यांकन के अंतिम चरण के रूप में नष्ट कर दिया जाता है जिसमें (शाब्दिक रूप से वह बिंदु होता है जहाँ वे बनाए गए थे)।
Wonder.mice

2
@ wonder.mice तो कृपया st के साथ T को बदलें: स्ट्रिंग; यहाँ सभी टेम्पलेटों का उपयोग करने की कोई आवश्यकता नहीं है, और T && का उपयोग r- मान के संदर्भ के रूप में करना केवल भयानक शैली है जो अनावश्यक रूप से लोगों को नए टेम्पलेट और r-मानों में भ्रमित करता है।
xdavidliu
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.