2014-09-10 15 views
19

को स्थानांतरित करना std::pair को बदलने का कोई तरीका है?एक std :: जोड़ी

std::unordered_map<int, std::pair<std::string, std::string>> my_map; 
my_map.emplace(1, "foo", "bar"); // Error 
पाठ्यक्रम डालने के

संभव है:

my_map[2] = std::make_pair("bar", "foo"); 

लेकिन यह आगे बढ़ अनावश्यक नकल की आवश्यकता नहीं है /?

उत्तर

19

क्या std :: pair को emplacing का कोई तरीका है?

तर्क pair<int, pair<string,string>> के एक निर्माता के लिए उपयुक्त होने की जरूरत है, नक्शे के value_type:

my_map.emplace(1, std::make_pair("foo", "bar")); 

लेकिन यह आगे बढ़ अनावश्यक नकल की आवश्यकता नहीं है /?

नहीं; make_pair स्ट्रिंग अक्षर के लिए पॉइंटर्स की एक जोड़ी बनाता है, जिसे तब शुरू करने के लिए उपयोग किया जाता है (emplace के मामले में) या मानचित्र में निहित स्ट्रिंग्स ([] के मामले में) को असाइन किया जाता है।

+2

उस पर विस्तार - 'emplace' कोई ऑब्जेक्ट नहीं बनाता है और फिर इसे कंटेनर में ले जाता है; यह कंटेनर पर तर्कों को आगे बढ़ाने के लिए * अग्रेषण * का उपयोग करता है, और उसके बाद कंटेनर ऑब्जेक्ट कन्स्ट्रक्टर को आमंत्रित करता है जब कंटेनर ने यह पता लगाया है कि स्मृति में जहां ऑब्जेक्ट बनाया गया है। (भ्रामक कार्य नाम!) –

0

हाँ है:

my_map.emplace(1, std::make_pair("foo", "bar")); 
16

इस मामले में वहाँ, "मूल्य-प्रकार" std::pair के कुछ हिस्सों emplacing std::string के रूप में छोटे से बिंदु है दोनों कुशलता से एक सी स्ट्रिंग से परिवर्तित किया जा सकता है, और यह कर सकते हैं मानचित्र में कुशलता से स्थानांतरित हो। सरल m.emplace(3, std::make_pair("bob", "alice")) और आप इष्टतम दक्षता के 99% रास्ते हैं।

हालांकि, अगर आप एक std::map कि एक प्रकार है कि कुशलता से इस तरह का निर्माण नहीं किया जा सकता करने के लिए नक्शे है, सी ++ 11 std::piecewise_constructstd::pair के लिए होने के लिए emplace घ प्रदान करता है।

struct A { }; // nothing 
struct C { C(C&&)=delete; }; // no copy/move 
struct B { B()=delete; B(B&&)=delete; B(C&&, C&&) {}; }; // no copy/move, only annoying ctor 

std::map< int, std::pair<A,B> > test; 
// test.emplace(0, std::make_pair(A{}, B{}); // does not compile 
// test.emplace(0, std::make_pair(A{}, B{C{},C{}}); // does not compile 
test.emplace(std::piecewise_construct, 
    std::make_tuple(0), 
    std::forward_as_tuple(
    std::piecewise_construct, 
    std::forward_as_tuple(A{}), 
    std::forward_as_tuple(C{}, C{}) 
) 
); // compiles! 

live example

यह एक कठोर कोने मामला है, के रूप में कुशल-चाल वस्तुओं कहीं अधिक आम हैं।

+3

एर। 'std :: piecewise_construct' सी ++ 11 है, सी ++ 14 नहीं। – Rapptz

+0

@ रैपेट्ज अच्छा बिंदु। – Yakk

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