एटॉमिक्स के वेक्टर का प्रारंभिककरण


12

विचार करें:

void foo() {
  std::vector<std::atomic<int>> foo(10);
  ...
}

क्या अब फू की सामग्री मान्य है? या क्या मुझे स्पष्ट रूप से लूप के माध्यम से और उन्हें इनिशियलाइज़ करने की आवश्यकता है? मैंने गॉडबोल्ट पर जाँच की है और यह ठीक लगता है, हालाँकि इस बिंदु पर मानक बहुत उलझा हुआ लगता है।

Std :: वेक्टर निर्माता यह सम्मिलित करता है का कहना है कि डिफ़ॉल्ट-डाला के उदाहरण std::atomic<int>है, जो कर रहे हैं initialised मूल्य प्लेसमेंट के माध्यम से new

मुझे लगता है कि मूल्य आरंभ का यह प्रभाव लागू होता है:

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

तो मुझे ऐसा लगता है कि परमाणु शून्य-प्रारंभिक हैं। तो सवाल यह है कि क्या std::atomic<int>किसी मान्य वस्तु में परिणाम का शून्य-आरंभ होता है ?

मैं अनुमान लगाने जा रहा हूं कि उत्तर "हां व्यवहार में है लेकिन यह वास्तव में परिभाषित नहीं है"?

नोट: यह उत्तर सहमत है कि यह शून्य-आरंभीकृत है, लेकिन वास्तव में यह नहीं कहता है कि इसका मतलब है कि वस्तु वैध है।

जवाबों:


7

आप चिंतित होने के लिए सही हैं। मानक के अनुसार एटमिक्स में डिफॉल्ट कंस्ट्रक्टर कहा जाता है, हालांकि उन्हें इस तरह से इनिशियलाइज़ नहीं किया गया है। ऐसा इसलिए है क्योंकि डिफ़ॉल्ट निर्माता परमाणु को इनिशियलाइज़ नहीं करता है:

डिफ़ॉल्ट-आरंभीकृत std::atomic<T>में कोई Tऑब्जेक्ट नहीं होता है , और इसके एकमात्र मान्य उपयोग विनाश और प्रारंभ द्वारा std :: atomic_init हैं

यह कुछ हद तक सामान्य भाषा के नियमों का उल्लंघन है, और कुछ कार्यान्वयन वैसे भी आरंभ करते हैं (जैसा आपने नोट किया है)।

कहा जा रहा है, मैं 100% सुनिश्चित करने के लिए अतिरिक्त कदम उठाने की सलाह दूंगा कि वे मानक के अनुसार सही ढंग से आरंभ किए गए हैं - आखिरकार आप संगामिति के साथ काम कर रहे हैं जहां बग को ट्रैक करना बेहद मुश्किल हो सकता है।

रैपर का उपयोग करने सहित समस्या को चकमा देने के कई तरीके हैं:

struct int_atomic {
   std::atomic<int> atomic_{0};//use 'initializing' constructor
};

या वास्तव में उपयोग करते हैं atomic_init। आपको पहले से ही प्रश्न में कोड के आसपास पहले से सिंक्रनाइज़ करना होगा
को ऑर्बिट

डिफ़ॉल्ट निर्माता तुच्छ है, इसलिए इसे वैसे भी नहीं कहा जाता है (प्रश्न में बोली के अनुसार)
कक्षा में लाइटनेस दौड़

@LightnessRaceswithMonica यह भी संभव है, मैं सिर्फ रैपर को हाइलाइट करना
चाहता हूं

@LightnessRaceswithMonica यह सामान्य भाषा के नियमों का एक अपवाद है - भले ही कुछ संकलक इस अपवाद को लागू नहीं करते हैं। मुझे यकीन नहीं है कि StoreTeller का उत्तर 100% सटीक है।
13

2

भले ही डिफ़ॉल्ट निर्माता को बुलाया गया था (यह नहीं है, क्योंकि यह तुच्छ है) यह वास्तव में कुछ भी नहीं करता है

शून्य-आरंभीकरण को स्पष्ट रूप से एक वैध परमाणु का उत्पादन करने की गारंटी नहीं दी जा सकती है; यह तभी काम करेगा जब संयोग से एक वैध परमाणु अपने सभी सदस्यों को शून्य-प्रारंभिक करके बनाया जाता है।

और, चूंकि एटॉमिक्स प्रतिलिपि योग्य नहीं हैं, इसलिए आप वेक्टर कंस्ट्रक्टर में एक प्रारंभिक मूल्य प्रदान नहीं कर सकते।

अब आपको कंटेनर और std::atomic_initप्रत्येक तत्व पर लूप करना चाहिए । यदि आपको इसके चारों ओर लॉक करने की आवश्यकता है, तो यह ठीक है क्योंकि आप पहले से ही उसी कारण से वेक्टर के निर्माण को सिंक्रनाइज़ कर रहे हैं।


@ डार्यून मैं मानता हूं कि एक प्रकार का सिंक्रोनाइजेशन;)
को ऑर्बिट
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.