2014-12-15 10 views
5

के साथ रैवल्यू को समाप्त करने के लिए लालसा decaying यदि प्रश्न शीर्षक गलत है, तो मैं क्षमा चाहता हूं - लेकिन मुझे यह समझने में कठिनाई हो रही है कि यहां क्या हो रहा है। ,ऑटो त्रुटि

void func(foo& f) { 
    foo bar{f}; 
} 
हालांकि

जब मैं ऑटो का उपयोग करें::

struct foo { 
    foo(foo&); 
}; 

निम्नलिखित कोई त्रुटि नहीं है:

निम्नलिखित वर्ग पर विचार करें

void func(foo& f) { 
    auto bar = foo{f}; 
} 

मैं (जीसीसी) मिलती है:

test.cpp: In function ‘void func(foo&)’: 
test.cpp:6:21: error: no matching function for call to ‘foo::foo(foo)’ 
test.cpp:6:21: note: candidate is: 
test.cpp:2:5: note: foo::foo(foo&) 
test.cpp:2:5: note: no known conversion for argument 1 from ‘foo’ to ‘foo&’ 

(बजना)

test.cpp:6:10: error: no matching constructor for initialization of 'bar' 
    auto bar = foo{f}; 
     ^ ~~~~~~ 
test.cpp:2:5: note: candidate constructor not viable: expects an l-value for 1st argument 
    foo(foo&); 
    ^

किसी कृपया समझा क्यों यह एक त्रुटि है?

धन्यवाद!

संपादित करें: यह काम करता है अगर मैं foo में एक प्रति-निर्माता जोड़ता हूं। हालांकि, मैं इस धारणा के तहत था कि परिवर्तनीय घोषणा + '=' वाक्यविन्यास के दाहिने तरफ कन्स्ट्रक्टर को स्पष्ट कॉल का विशेष रूप से इलाज किया जाता है और यह एक प्रति-निर्माण नहीं बल्कि प्रत्यक्ष प्रारंभिकता है।

उत्तर

8
auto bar = foo{f}; 

autofoo के रूप में निष्कर्ष निकाला गया है। इसके बाद, अपनी परिभाषा के

foo bar = foo{f}; 

आप प्रकार foo की एक वस्तु है कि prvalue foo{f} साथ कॉपी-प्रारंभ बनाने के लिए कोशिश कर रहे हैं बराबर है।

समस्या यह है कि foo की कॉपी कन्स्ट्रक्टर में इसके पैरामीटर के रूप में एक गैर-कॉन्स लैवल्यू संदर्भ है, जो एक रावल्यू से बांधना असंभव है। साथ ही, चालक कन्स्ट्रक्टर को निश्चित रूप से परिभाषित नहीं किया गया है क्योंकि आपके पास उपयोगकर्ता द्वारा घोषित प्रतिलिपि निर्माता है। इसलिए कोई कंस्ट्रक्टर नहीं है जो foo{f} ले सकता है, और संकलक एक त्रुटि संदेश जारी करता है।

+0

क्या संकलक कॉपी कन्स्ट्रक्टर को कॉल छोड़ देगा? मैं इस धारणा के तहत था कि संकलक इसे सीधे प्रारंभिक रूप में मानेंगे। –

+0

एंड्रॉइड पर अहह टाइपिंग धीमा है, और –

+0

@RobertMason संकलक को प्रतिलिपि बनाने का कोई तरीका नहीं है संकलक एक प्रतिलिपि बनाने वाले को कॉल कर सकता है जिसका कोई दुष्प्रभाव नहीं है, लेकिन कॉपी कन्स्ट्रक्टर अभी भी कॉल करने योग्य होना चाहिए। – Oktalist

3
auto bar = foo{f}; 

यह प्रति-प्रारंभिक है, और इसके अर्थशास्त्र द्वारा इसे प्रतिलिपि बनाने की आवश्यकता है। हालांकि, foo की कॉपी कन्स्ट्रक्टर गैर-कॉन्स्ट संदर्भ लेता है, और गैर-कॉन्स्ट संदर्भ अस्थायी नहीं हो सकता है, यह foo{f} है।

समाधान एक कॉपी कन्स्ट्रक्टर बनाना है जो कॉन्स संदर्भ लेता है, क्योंकि कॉपी कन्स्ट्रक्टर आमतौर पर करते हैं।

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