2014-12-02 4 views
6

कक्षा S के ऑब्जेक्ट s के नीचे दिए गए कोड में D की ऑब्जेक्ट को प्रारंभ-प्रारंभिक D d(s); के साथ प्रारंभ करने के लिए उपयोग किया जाता है। रूपांतरण फ़ंक्शन S :: ऑपरेटर डी() का उपयोग s को D प्रकार की अस्थायी वस्तु में बदलने के लिए किया जाता है। फिर, इस अस्थायी वस्तु को d में स्थानांतरित करने के लिए, gcc और clang दोनों चालक कन्स्ट्रक्टर D(&&) पर स्पष्ट कॉल को बढ़ाएं। live example देखें।जीसीसी और क्लैंग दोनों नीचे स्निपेट में चालक कन्स्ट्रक्टर को कॉल को बढ़ाएं। क्या ये सही है?

#include <iostream> 
struct D; 
struct S{ operator D(); }; 

struct D{ 
    D(){} 
    D(D&&) { std::cout << "move constructor" << '\n'; } 
}; 

S::operator D() { std::cout << "conversion function" << '\n'; return D(); } 

int main() 
{ 
    S s; 
    D d(s); 
} 

मैं, इस इलिजन के सही होने पर विवाद कर रहा हूँ निम्नलिखित आधार पर:

  1. इस मामले §8.5/16 (N3337) में पहले उप बुलेट बिंदु में शामिल है, जो है elision के बारे में चुप।

    प्रारंभ डायरेक्ट-प्रारंभ है, या यदि वह कॉपी-आरंभीकरण है जहां स्रोत प्रकार के सीवी-अयोग्य संस्करण के रूप में एक ही कक्षा, या के एक व्युत्पन्न वर्ग, गंतव्य के वर्ग है , रचनाकारों पर विचार किया जाता है। लागू कन्स्ट्रक्टर गणना (13.3.1.3) हैं, और सबसे अच्छा अधिभार रिज़ॉल्यूशन (13.3) के माध्यम से चुना जाता है। इस प्रकार चयनित कन्स्ट्रक्टर को ऑब्जेक्ट को आरंभ करने के लिए कहा जाता है, प्रारंभकर्ता अभिव्यक्ति या अभिव्यक्ति-सूची के साथ तर्क (ओं) के रूप में। यदि कोई कन्स्ट्रक्टर लागू नहीं होता है, या अधिभार संकल्प संदिग्ध है, प्रारंभिकता खराब है।

  2. ध्यान दें कि अगला उप-बुलेट बिंदु स्पष्ट रूप से elision की संभावना का उल्लेख करता है।
  3. चालक कन्स्ट्रक्टर को कॉल स्पष्ट है। इसे कैसे बढ़ाया जा सकता है?

उत्तर

8

सी ++ मानक एक स्थान पर एक पूरी तरह से अलग जगह में परिभाषित नियमों के अपवाद बनाने के लिए प्यार करता है।

कॉपी/चाल elision नियम 12.8/31 में निर्दिष्ट हैं। आपके कोड में दो प्रतिलिपि/चाल अभियान समाप्त हो सकते हैं।

पहला आसान है: operator D के भीतर, वापसी अभिव्यक्ति में अस्थायी रूप से निर्मित अस्थायी में स्थानांतरित किया जाता है जो फ़ंक्शन रिटर्न मान का प्रतिनिधित्व करता है। बुलेट 3 इस कदम के elision की अनुमति देता है।

दूसरा अस्थायी फ़ंक्शन रिटर्न मान d ऑब्जेक्ट का स्थान है। फिर, बुलेट 3 elision की अनुमति देता है।

  • जब एक अस्थायी वर्ग वस्तु है कि एक संदर्भ (12.2) के लिए बाध्य नहीं किया गया कॉपी किया जाएगा/एक ही सीवी-अयोग्य प्रकार के साथ एक वर्ग वस्तु में ले जाया गया, कॉपी/कदम आपरेशन द्वारा हटाया जा सकता है अस्थायी वस्तु को सीधे छोड़ी गई प्रतिलिपि/चाल
के लक्ष्य में सीधे अस्थायी वस्तु का निर्माण
संबंधित मुद्दे