2011-01-29 10 views
11

यह documentation के अनुसार:कैसे बढ़ावा देता है :: unordered_map.emplace (Args && ... args) काम करता है?

आवेषण एक वस्तु, कंटेनर यदि और केवल यदि वहाँ एक बराबर कुंजी के साथ कंटेनर में कोई तत्व है में, तर्क आर्ग के साथ निर्माण किया।

लेकिन केवल वस्तुओं जो एक unordered_map में डाला जा सकता प्रकार std::pair<Key const, Mapped> (क्योंकि दोनों एक प्रमुख और एक मूल्य के लिए एक वस्तु के लिए आवश्यक हैं सम्मिलित करने के लिए) है, जो ठीक दो तर्क के साथ एक निर्माता लेने के लिए जाना जाता है। तो यह वैरैडिक फ़ंक्शन फॉर्म का उपयोग क्यों करता है? निश्चित रूप से ऐसा कुछ है जिसे मैं पूरी तरह से समझ नहीं पा रहा हूं।

उत्तर

8

this emplace_back बनाम push_back पर SO लेख देखें। अनिवार्य रूप से, यह ऑब्जेक्ट को पहले से पारित करने के लिए ऑब्जेक्ट बनाने की आवश्यकता के बिना इसमें दिए गए तर्कों से निर्मित किया जा सकता है। यह एक प्रति निर्माण को हटाकर ओवरहेड पर बचाता है जो आमतौर पर वस्तुओं को बनाने के परिणामस्वरूप होता है।

तो आप इस के साथ भाग प्राप्त कर सकते हैं:

unordered_map<int,int> foo; 
foo.emplace(4, 5); 
बजाय

foo.insert(std::make_pair(4, 5)); 

और भी बेहतर, (और अगर मैं गलत नहीं हूँ), तो आप इस मार्ग के माध्यम से जा सकते हैं:

struct Bar{ 
    int x,y; 
    Bar(int _x, int _y) : x(_x), y(_y){} 
}; 

unordered_map<int,Bar> baz; 
baz.emplace(4, 5, 6); 

और C++0x पर विकी से लिया:

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

कौन सा निम्नलिखित तरीके से काम करता है:

template<typename TypeToConstruct> struct SharedPtrAllocator { 

    template<typename ...Args> std::shared_ptr<TypeToConstruct> construct_with_shared_ptr(Args&&... params) { 
     return std::shared_ptr<TypeToConstruct>(new TypeToConstruct(std::forward<Args>(params)...)); 
    } 
} 

फिर, बेशर्म विकी लेख ऊपर उल्लेख से चोरी हो।

+0

का निर्माण करने वाला दूसरा दूसरा उदाहरण मुझे अजीब लगता है। मान लीजिए कि हमारे पास 'कुंजी' के लिए 2 कन्स्ट्रक्टर हैं:' कुंजी (int) 'और' कुंजी (int, int) 'और' 'value' के लिए' 'मान (int, int)' और 'मान (int) ', कैसा है एक 'कुंजी/वैल्यू' जोड़ी बनाने के मामले में संकलक असंबद्ध होने जा रहा है? –

+0

पहले आओ, पहले मैंने सेवा की थी? तो यह पहले 'एक्स (int, int)' बनाता है और फिर 'एक्स (int) 'बनाता है। बाद में इसका परीक्षण करेंगे और वापस पोस्ट करेंगे। शायद संकलित न करें और "महत्वाकांक्षी" संकलन समय त्रुटि फेंक दें। – Xeo

+0

@Maththieu एम। वास्तव में, कोई विचार नहीं। समस्या यह है कि spec वर्तमान में पूरी तरह से औपचारिक रूप से लागू नहीं है और इसलिए हम यह सुनिश्चित नहीं कर सकते कि इस प्रकार के प्रश्न का उत्तर तब तक दिया जाना चाहिए जब तक कि यह नहीं है। हमें जो चाहिए वह एक भाषा वकील है जो मेरे जवाब में आने वाली अस्पष्टताओं को खत्म करने और साफ़ करने के लिए है। मैं इसे दिल की धड़कन में वोट दूंगा। – wheaties

5

अब जब कि सी ++ स्टैंडर्ड लाइब्रेरी बूस्ट का वह हिस्सा एकीकृत किया गया है:

से http://en.cppreference.com

#include <iostream> 
#include <utility> 
#include <tuple> 

#include <unordered_map> 

int main(){ 
    std::unordered_map<std::string, std::string> m; 

    // uses pair's piecewise constructor 
    m.emplace(std::piecewise_construct, 
     std::forward_as_tuple("c"), 
     std::forward_as_tuple(10, 'c')); 

    for (const auto &p : m) { 
     std::cout << p.first << " => " << p.second << '\n'; 
    } 
} 

std::piecewise_construct एक निरंतर कि कैसे तर्क

उपयोग किया जाएगा के बारे में कोई अस्पष्टता नहीं छोड़ देता है
  • पहला टुपल का उपयोग करने के लिए किया जाएगा संरचना
  • मूल्य
संबंधित मुद्दे