2012-03-08 12 views
5

जब मैं ideone पर निम्नलिखित संकलन करने का प्रयास:मानक लाइब्रेरी में + = वैध अस्थायी क्यों हैं?

class X 
{ 
    public: 
    friend X& operator+=(X& x, const X& y); 
}; 

X& operator+=(X& x, const X& y) { return x; } 

int main() 
{ 
    X() += X(); 
} 

जैसी उम्मीद थी, इस एक संकलन त्रुटि फेंकता है, क्योंकि आप एक गैर स्थिरांक संदर्भ के लिए एक अस्थायी पारित नहीं कर सकते हैं।

हालांकि, निम्नलिखित ideone पर सफलतापूर्वक संकलित:

std::string() += std::string(); 

नहीं चाहिए ऊपर मेरी उदाहरण की तरह इस त्रुटि?

संपादित करें:

std :: स्ट्रिंग() एक सदस्य के रूप में आपरेशन += को परिभाषित करता है, तो क्यों यह इस करता है जब इस तरह के उपयोग बाएं हाथ की ओर एक अस्थायी होने के लिए अनुमति देता है? जैसा कि मैंने ऊपर दिया है और अस्थायी मुद्दों के संदर्भ से बचें, इसे क्यों परिभाषित नहीं करें?

+0

रिकॉर्ड के लिए वीसी ++ 10.0 में संकलन के साथ दोनों चेतावनी 'चेतावनी C4239: गैर-मानक विस्तार का उपयोग:' तर्क ':' एक्स 'से' एक्स '' –

+1

@DougT में रूपांतरण।: वीएस एक विस्तार के रूप में गैर-कॉन्स रेफ को बाध्यकारी temps की अनुमति देता है, इसलिए उत्तर देने के बाद प्रश्न को मूल रूप से बदलने के लिए –

+1

-1 पर इसका परीक्षण करने के लिए यह उपयोगी टूलचैन नहीं है। अछा नहीं लगता। यदि आपके पास फॉलो-अप है - एक अलग प्रश्न पूछें, मूल उत्तर देने के बाद पूरी तरह से कुछ और पूछने के लिए अपने स्वयं के प्रश्न को हाइजैक न करें। – littleadv

उत्तर

6

महसूस सी ++ नियम यह है कि आप एक गैर स्थिरांक संदर्भ के लिए एक अस्थायी बाध्य नहीं कर सकता है। हालांकि, आप अस्थायी पर गैर-कॉन्स सदस्य फ़ंक्शन को कॉल कर सकते हैं: यदि आप सदस्य के रूप में operator +=() को परिभाषित करते हैं, तो आप इसे अपने ऑब्जेक्ट पर कॉल कर सकते हैं। अस्थायी रूप से संदर्भ कैसे प्राप्त करें, यह एक चाल है। जब एक अस्थायी std::istringstream का उपयोग कर एक गैर बुनियादी प्रकार पढ़ने के लिए (बुनियादी प्रकार के सदस्यों द्वारा पढ़ा जाता है):

std::string word; 
if (std::istringstream("hello world") >> std::ws >> word) { ... } 

(हाँ, इस है एक मूर्खतापूर्ण उदाहरण)।

3

क्योंकि यह const है।

string::operator+=

X& operator+=(const X& y) के लिए बदल अपने कोड बस के रूप में अच्छी तरह से ठीक संकलन कर देगा।

संपादित

आप सवाल बदल के बाद मैं यह पहले से ही उत्तर दिया है और अपने X::operator+= की परिभाषा ही बदल के बजाय एक friend समारोह एक सदस्य समारोह होने के लिए। यह वास्तव में काम नहीं करेगा। ध्यान दें कि std::string::operator+=friend नहीं है, यह std::string का सदस्य कार्य है।

+0

ओह, अब मैंने सवाल को संशोधित किया है। मानक पुस्तकालय ऑपरेटर को परिभाषित क्यों नहीं करता है + = जैसा कि मैंने ऊपर किया है? – Clinton

+0

अच्छी तरह से, शायद "x + = string (" y ") को अनुमति देने के लिए;" काम करने के लिए, उदाहरण के लिए। मुझे कोई कारण नहीं दिख रहा है कि इसे क्यों अनुमति नहीं देनी चाहिए। यदि आपको किसी अन्य स्ट्रिंग में जोड़ने के लिए केवल कुछ प्रकार को std :: स्ट्रिंग में कनवर्ट करने की आवश्यकता है, तो इस तरह से ऐसा क्यों न करें? – littleadv

+0

मुझे यकीन नहीं है कि आपका मतलब क्या है "अनुमति दें x x = = string (" y "); 'काम करने के लिए। उदाहरण मैं देता हूं' x + = string (" y ");', लेकिन 'स्ट्रिंग (" x ") + = स्ट्रिंग ("y") '। – Clinton

3
string& operator+= (const string& str); 

अंतर

0

operator+= आम तौर पर एक सदस्य समारोह के रूप में ओवरलोड हो गया है, और सदस्य कार्य (const या अन्यथा) अस्थायी rvalues ​​ पर कहा जा सकता है।

यदि आप किसी सदस्य, X& operator+=(const X&) पर अपना अधिभार बदलते हैं, तो आपका उदाहरण संकलित भी होना चाहिए।

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