चूंकि C ++ 17 std::map
दो नए सम्मिलन के तरीके प्रदान करता है: insert_or_assign()
और try_emplace()
, जैसा कि sp2danny द्वारा टिप्पणी में भी उल्लेख किया गया है ।
insert_or_assign()
असल में, insert_or_assign()
का "सुधार" संस्करण है operator[]
। इसके विपरीत operator[]
, insert_or_assign()
डिफ़ॉल्ट रूप से निर्माण के लिए मानचित्र के मान प्रकार की आवश्यकता नहीं होती है। उदाहरण के लिए, निम्न कोड संकलित नहीं करता है, क्योंकि MyClass
एक डिफ़ॉल्ट निर्माता नहीं है:
class MyClass {
public:
MyClass(int i) : m_i(i) {};
int m_i;
};
int main() {
std::map<int, MyClass> myMap;
// VS2017: "C2512: 'MyClass::MyClass' : no appropriate default constructor available"
// Coliru: "error: no matching function for call to 'MyClass::MyClass()"
myMap[0] = MyClass(1);
return 0;
}
हालाँकि, यदि आप myMap[0] = MyClass(1);
निम्न पंक्ति से प्रतिस्थापित करते हैं, तो कोड संकलित करता है और प्रविष्टि उद्देश्य के अनुसार होती है:
myMap.insert_or_assign(0, MyClass(1));
इसके अलावा, के लिए इसी तरह insert()
, insert_or_assign()
एक रिटर्न pair<iterator, bool>
। बूलियन मान true
एक प्रविष्टि हुआ है और false
यदि एक असाइनमेंट किया गया था। पुनरावृत्त उस तत्व को इंगित करता है जिसे सम्मिलित या अद्यतन किया गया था।
try_emplace()
उपरोक्त के समान, try_emplace()
का एक "सुधार" है emplace()
। इसके विपरीत emplace()
, try_emplace()
यदि नक्शे में पहले से मौजूद एक कुंजी के कारण सम्मिलन विफल हो जाता है, तो इसके तर्कों को संशोधित नहीं करता है। उदाहरण के लिए, निम्नलिखित कोड एक कुंजी के साथ एक तत्व को निकालने का प्रयास करता है जो पहले से ही नक्शे में संग्रहीत है (देखें *):
int main() {
std::map<int, std::unique_ptr<MyClass>> myMap2;
myMap2.emplace(0, std::make_unique<MyClass>(1));
auto pMyObj = std::make_unique<MyClass>(2);
auto [it, b] = myMap2.emplace(0, std::move(pMyObj)); // *
if (!b)
std::cout << "pMyObj was not inserted" << std::endl;
if (pMyObj == nullptr)
std::cout << "pMyObj was modified anyway" << std::endl;
else
std::cout << "pMyObj.m_i = " << pMyObj->m_i << std::endl;
return 0;
}
आउटपुट (कम से कम VS2017 और कोलिरु के लिए):
pMyObj डाला नहीं गया था
pMyObj को वैसे भी संशोधित किया गया था
जैसा कि आप देख सकते हैं, pMyObj
अब मूल वस्तु की ओर इशारा नहीं करता है। हालाँकि, यदि आप auto [it, b] = myMap2.emplace(0, std::move(pMyObj));
निम्न कोड से प्रतिस्थापित करते हैं, तो आउटपुट अलग दिखता है, क्योंकि pMyObj
अपरिवर्तित रहता है:
auto [it, b] = myMap2.try_emplace(0, std::move(pMyObj));
आउटपुट:
pMyObj डाला नहीं गया था
pMyObj pMyObj.m_i = 2
कोलीरू पर कोड
कृपया ध्यान दें: मैंने अपने स्पष्टीकरण को इस उत्तर में फिट करने के लिए यथासंभव संक्षिप्त और सरल रखने की कोशिश की। अधिक सटीक और व्यापक विवरण के लिए, मैं धाराप्रवाह सी ++ पर इस लेख को पढ़ने की सलाह देता हूं ।