2011-05-28 15 views
21

N3059 में मुझे के टुकड़े के निर्माण जोड़े (और टुपल्स) का विवरण मिला (और यह नए मानक में है)।सी ++ 11 उपयोग-केस जोड़ी और tuple के piecewise_construct के लिए?

लेकिन मुझे नहीं पता कि मुझे इसका उपयोग कब करना चाहिए। मुझे और गैर-प्रतिलिपि योग्य इकाइयों के बारे में चर्चाएं मिलीं, लेकिन जब मैंने इसे आजमाया, तो मैं एक ऐसा केस नहीं बना सका जहां मैं piecewiese_construct की आवश्यकता हो या प्रदर्शन लाभ देख सकूं।

उदाहरण। मैंने सोचा कि मैं एक वर्ग जो गैर copyable है की जरूरत है, लेकिन movebale (अग्रेषित करने के लिए आवश्यक):

struct NoCopy { 
    NoCopy(int, int) {}; 
    NoCopy(const NoCopy&) = delete; // no copy 
    NoCopy& operator=(const NoCopy&) = delete; // no assign 
    NoCopy(NoCopy&&) {}; // please move 
    NoCopy& operator=(NoCopy&&) {}; // please move-assign 
}; 

मैं तो तरह-की उम्मीद है कि मानक जोड़ी-निर्माण विफल हो जाएगा:

pair<NoCopy,NoCopy> x{ NoCopy{1,2}, NoCopy{2,3} }; // fine! 

लेकिन ऐसा नहीं हुआ। दरअसल, वही है जो मैं वैसे भी चाहता था, क्योंकि "चारों ओर घूमना" बल्कि फिर इसे हर जगह stdlib में कॉपी करना, यह होना चाहिए।

pair<NoCopy,NoCopy> y(
    piecewise_construct, 
    forward_as_tuple(1,2), 
    forward_as_tuple(2,3) 
); // also fine 
  • तो, क्या एक USECASE है:

    इस प्रकार, मैं कोई कारण नहीं क्यों मैं इस, या ऐसा किया है चाहिए?

  • कैसे और कब क्या मैं piecewise_construct का उपयोग करता हूं?
+0

चाल निर्माता अक्षम करने भी कोशिश करें। –

उत्तर

28

प्रतिलिपि की तुलना में सभी प्रकारों को अधिक कुशलता से स्थानांतरित नहीं किया जा सकता है, और कुछ प्रकार के लिए यह कॉपी और चलने दोनों को स्पष्ट रूप से अक्षम करने का भी अर्थ हो सकता है।को एक प्रकार के पूर्व प्रकार के उदाहरण के रूप में देखें।

emplace कार्य करता है और piecewise_construct साथ मुद्दा यह है कि इस तरह के एक वर्ग जगह में निर्माण किया जा सकता, अस्थायी उदाहरणों को बनाए बिना ही चले गए या कॉपी किया जा रहा है।

struct big { 
    int data[100]; 
    big(int first, int second) : data{first, second} { 
     // the rest of the array is presumably filled somehow as well 
    } 
}; 

std::pair<big, big> pair(piecewise_construct, {1,2}, {3,4}); 

pair(big(1,2), big(3,4)) के लिए ऊपर की तुलना करें जहां दो अस्थायी big वस्तुओं और बनाया जाना तो नकल कर ली है होगा - और चलती बिल्कुल यहाँ मदद नहीं करता है! इसी तरह:

std::vector<big> vec; 
vec.emplace_back(1,2); 

मुख्य उपयोग के मामले piecewise एक जोड़ी के निर्माण के लिए एक map या एक unordered_map में तत्वों emplacing है:

std::map<int, big> map; 
map.emplace(std::piecewise_construct, /*key*/1, /*value*/{2,3}); 
+1

आपने वर्णन किया कि काफी अच्छी तरह से धन्यवाद। और मैंने जो भी सोचा, वह भी। लेकिन 'जोड़ी (piecewise_construct, ...)' काम नहीं करती है यदि आप ** लक्ष्य वर्ग ** पर चलना अक्षम करते हैं ('= delete' के साथ)। मैंने इसे gcc-4.7.0 के साथ करने की कोशिश की और * संकलन त्रुटि मिली *। कारण: 'जोड़ी 'का कार्यान्वयन:
' टेम्पलेट <वर्ग ... _Args1, कक्षा ..._Args2> जोड़ी (piecewise_construct_t, टपल <_Args1...> __first, टपल <_Args2...> __second): पहला (__ विपक्ष (std :: चाल (__ पहले))), दूसरा (__ विपक्ष (std :: चाल (__ दूसरा))) {} 'के रूप में आप कर सकते हैं देखें, एक ** चाल ** आवश्यक है। ** emplace ** का उपयोग नहीं किया प्रतीत होता है। – towi

+0

ठीक है, ऐसा लगता है कि gcc-4.7.0 अभी तक 'map.emplace()' प्रदान नहीं करता है। लेकिन यह अभी भी 'जोड़ी (piecewise_construct, {...}, {...}) के बारे में मेरा प्रश्न छोड़ देता है। क्या यह * गैर-प्रतिलिपि * ** और ** * गैर-चलने योग्य * वस्तुओं के साथ काम करना चाहिए? एसडी 20.3.2 में फॉर्मूलेशन से। (14) यह ऐसा प्रतीत हो सकता है। यद्यपि "अग्रेषण" को हटा दिया गया है, लेकिन यह रचनाकारों के तर्कों पर लागू होता है, न कि वस्तुओं पर (जहां एक कदम की आवश्यकता हो सकती है?)। – towi

+0

@towi: मुझे लगता है कि gcc-4.7.0 + libstdC++ pairwise_construct के साथ जोड़ी कन्स्ट्रक्टर के लिए अभी तक अनुपालन नहीं है। गैर-प्रतिलिपि योग्य और गैर-चलने योग्य वस्तु को काम करना चाहिए और उदाहरण के लिए क्लैंग + libC++ सही परिणाम दे। @ जोहान्सडी: मुझे समझ में नहीं आता कि आप नक्शा क्यों सोचते हैं। जगह को टुकड़े टुकड़े के साथ काम करना चाहिए? मुझे लगता है कि हर प्रस्ताव को यह इंगित करना प्रतीत होता है कि प्रतिस्थापन का उपयोग 'map.emplace (कुंजी, ArgForValue ...)' होना चाहिए, उदाहरण के लिए 'map.emplace (/ * key */1,/* मान */2, 3); '(और यह है कि कैसे clang + libC++ व्यवहार) –

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

  • कोई संबंधित समस्या नहीं^_^