2012-04-19 7 views
12

जब मैं निम्नलिखित (छ ++ 4.6.3)सी ++ ऑपरेटर अधिभार: ऑब्जेक्ट से संदर्भ में कोई ज्ञात रूपांतरण नहीं?

class A {}; 

A& operator*=(A& a, const A& b) 
{ 
    return a; 
} 

A operator*(const A& a, const A& b) 
{ 
    return A(a) *= b; 
} 

int main(int, char*[]) 
{ 
    A a, b; 

    a = a*b; 

    return 0; 
} 

मैं त्रुटि मिलती है संकलन करने की कोशिश

/tmp/test.cxx: In function ‘A operator*(const A&, const A&)’: 
/tmp/test.cxx:14:20: error: no match for ‘operator*=’ in ‘(* & a) *= b’ 
/tmp/test.cxx:14:20: note: candidate is: 
/tmp/test.cxx:6:1: note: A& operator*=(A&, const A&) 
/tmp/test.cxx:6:1: note: no known conversion for argument 1 from ‘A’ to ‘A&’ 

यह पहेली मुझे - कैसे कर सकते हैं कि वर्ग के लिए एक संदर्भ के लिए एक वर्ग से एक रूपांतरण ज्ञात नहीं है?

के रूप में इस प्रकार का कोई प्रभाव नहीं होता है वर्ग ए की घोषणा बदलना:

class A 
{ 
public: 
    A() {} 
    A(const A&) {} 
}; 

एक ही त्रुटि।

मैं यहां क्या हो रहा है के संकेतों के लिए बहुत आभारी हूं।

+0

ऑपरेटर को कक्षा के दायरे में घोषित करके आप इस समस्या को ठीक कर सकते हैं। फिर आपकी विधि हस्ताक्षर इस तरह दिखेगा: 'ऑपरेटर * (कॉन्स ए और आरएएस) कॉन्स;' यदि आप कार्यान्वयन के लिए कंपाउंड ऑपरेटर का उपयोग करना चाहते हैं तो आप लिख सकते हैं: 'वापसी * ​​यह * = rhs' – Paranaix

+0

@ पाराएक्सएक्स: नहीं, आप 'const' के अंदर '* this' पर 'ऑपरेटर * =' का उपयोग नहीं कर सकते सदस्य समारोह, क्योंकि यह '* यह 'संशोधित करेगा। –

+0

@BenVoigt: हाँ आपका पूरा अधिकार है। मैं इसे एक लाइनर के रूप में लिखना चाहता था और गलती से पूरे जादू को हटा दिया। यह चाल 'इस' से एक प्रतिलिपि बनाना है। उदाहरण में: 'एक ret = * यह; ret * = rhs; वापसी वापस; ' – Paranaix

उत्तर

13

लुसियान की तरह, आप एक अस्थायी वस्तु को गैर-कॉन्स्ट संदर्भ में बाध्य नहीं कर सकते हैं। संकलक की अपेक्षा यह है कि अभिव्यक्ति के बाद वस्तु अस्तित्व में रहेगी, इसलिए इसे संशोधित करने का कोई मतलब नहीं है।

अपने कोड को ठीक करने के लिए, अस्थायी हटाने (बनाने तर्क const&operator *= में कोई मतलब नहीं है):

A operator*(A a, const A& b) 
{ 
    return a *= b; 
} 
+0

@बेन मुझे कॉफी चाहिए ... मेरे सम्मान की रक्षा करने के लिए, यह (मूल्य से गुजरना) यह है कि जब मैं जाग रहा हूं तो मैं इसे सामान्य रूप से कैसे लिखूंगा। –

+0

बहुत आसान है। और अधिक अनुकूलित, क्योंकि वास्तविक पैरामीटर एक एक्स-मान होने पर यह स्थानांतरित हो सकता है। –

5

जब आप A(a) लिखते हैं, आप ग्रुप ए (एक rvalue) की एक अस्थायी बनाने जिसकी आप प्रतिलिपि a के साथ-साथ निर्माण करें। सी ++ कहता है कि गैर रद्दी संदर्भ के रूप में कोई रावल पारित नहीं किया जा सकता है। विजुअल स्टूडियो इस नियम के बारे में थोड़ा सा गड़बड़ है, लेकिन जीसीसी और इसे लागू करने की तरह।

ठीक करने के लिए, इसे आजमाएं (जो बिल्कुल वही है, लेकिन आप उस चर को नाम देकर एक लाभा बनाते हैं)। एल- और आर-वैल्यू here

A operator*(A a, const A& b) 
{ 
    return a *= b; 
} 
+2

जैसा कि मैंने कोनराड के उत्तर पर पोस्ट किया था उसी तरह आपत्ति। –

+0

दोनों सही हैं। लेकिन कभी-कभी, आपको * ऑपरेशन करने के लिए एक की एक प्रति बनाने की आवश्यकता नहीं होती है। जैसे वेक्टर * ऑपरेटर * = – crazyjul

+0

व्यक्त करने के लिए * = विज़ुअल स्टूडियो का उपयोग नहीं करेगा ... "विजुअल स्टूडियो इसे पकड़ता है यदि आप चेतावनी स्तर 4 पर चल रहे हैं/चेतावनियों को त्रुटियों के रूप में देखते हैं (जैसा कि बुद्धिमान है) । वेक्टर उदाहरण में – mwigdahl

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