2010-11-04 10 views
15

के साथ चाल semantics का उपयोग करना मान लीजिए कि आप चाल semantics का लाभ लेना चाहते हैं, लेकिन आपके चलने योग्य वर्गों में से एक std::pair का हिस्सा होना चाहिए। इसका उद्देश्य एक ऐसा फ़ंक्शन बनाना होगा जो std::pair लौटाता है जिसे एक रैवल्यू के रूप में माना जा सकता है, और इसके साथ अग्रेषित किया जा सकता है।std :: pair या std :: tuple

लेकिन मैं नहीं देख सकता कि यह कैसे किया जा सकता है, जब तक std::pair में आंतरिक परिवर्तन स्वयं को सैमसंगिक्स के बारे में जागरूक करने के लिए नहीं बनाया जाता है।

पर विचार करें निम्नलिखित कोड:

struct Foo 
{ 
Foo() { } 

Foo(Foo&& f) { } 

private: 

Foo(const Foo& f) { } // do not allow copying 
}; 

int main() 
{ 
Foo f; 
std::pair<Foo, int> res = std::make_pair(f, 10); // fails due to private copy constructor 
} 

समस्या यह है कि std::make_pair है, साथ ही std::pair निर्माता ही है, दो वस्तुओं लेता है और उनमें से आंतरिक प्रतियां बनाने की कोशिश करता है। यह कॉपी कन्स्ट्रक्टर को आज़माने और आमंत्रित करने का कारण बनता है। लेकिन मेरे उदाहरण में, मैं को नई जोड़ी res में स्थानांतरित करने में सक्षम होना चाहता हूं, और सुनिश्चित करता हूं कि कोई प्रतियां नहीं बनाई गई हैं। मुझे लगता है कि होगा यह संभव है जब तक कि std::pair ही निम्नलिखित निर्माता आंतरिक रूप में परिभाषित किया गया था नहीं होगा:

pair(T1&& t1, T2&& t2) : first(std::move(t1)), second(std::move(t2)) 

लेकिन यह संकलक मैं (जीसीसी 4.3.2) का उपयोग कर रहा पर कम से कम नहीं, नहीं करता है। यह हो सकता है कि मेरा कंपाइलर बस पुराना है, और वास्तव में में नए संस्करण इस कदम-जागरूक निर्माता हैं। लेकिन इस समय चलने वाले अर्थशास्त्र की मेरी समझ कुछ हद तक कमजोर है, इसलिए मुझे यकीन नहीं है कि मैं बस यहां कुछ दिख रहा हूं। तो, क्या मैं वास्तव में संभवतः पूरा करने की कोशिश कर रहा हूं, वास्तव में std::pair को फिर से कार्यान्वित किए बिना? या मेरा संकलक अभी पुराना है?

उत्तर

16

यह std::pair कन्स्ट्रक्टर नहीं है जिसे यद्यपि कहा जाएगा। std::pair चाल निर्माता कहा जाता हो जाएगा, और इस कदम निर्माता कि वास्तव में आप क्या उम्मीद (N3126 20.3.5.2/6) करना चाहिए:

template<class U, class V> pair(pair<U, V>&& p); 

प्रभाव: निर्माता पहले std::move(p.first) साथ और std::move(p.second) के साथ दूसरे initializes।

हालांकि, अपने उदाहरण असफल चाहिए, क्योंकि std::make_pair(f, 10); में, f एक lvalue है और होना करने के लिए स्पष्ट रूप से move घ की जरूरत है, अन्यथा यह की नकल की है। निम्नलिखित कार्य करना चाहिए:

std::pair<Foo, int> res = std::make_pair(std::move(f), 10); 
+0

इसके अलावा, आपके संकलक जाँच std :: make_pair की उचित भार के है। आपको सीधे std :: जोड़ी कन्स्ट्रक्टर का उपयोग करने की आवश्यकता हो सकती है। – user9876

2

जीसीसी 4.3.2 में पूर्ण कार्यान्वयन नहीं होना चाहिए। जोड़ी (और टपल) चाल कंस्ट्रक्टर्स होगा:

template<class U, class V> pair(U&& x, V&& y); 
प्रभाव: निर्माता std :: आगे (x) और एसटीडी के साथ दूसरे आगे :: (y) के साथ पहले initializes।
template<class U, class V> pair(pair<U, V>&& p); 
प्रभाव: निर्माता std :: चाल (p.first) और std :: चाल (p.second) के साथ दूसरे के साथ पहली initializes।

([pairs.pair] से n3126 में)