"ओडीआर-उपयोग" का क्या मतलब है?


93

यह सिर्फ एक और सवाल के संदर्भ में सामने आया ।

क्लास टेम्प्लेट में स्पष्ट रूप से सदस्य फ़ंक्शन केवल तभी त्वरित रूप से किए जाते हैं यदि वे ODR- उपयोग किए जाते हैं। क्या कोई इसका मतलब समझा सकता है। एक परिभाषा नियम (ओडीआर) पर विकिपीडिया लेख "का उल्लेख नहीं करता ओडीआर उपयोग "।

हालाँकि मानक इसे परिभाषित करता है

एक चर जिसका नाम संभावित मूल्यांकन अभिव्यक्ति के रूप में प्रकट होता है , इसका उपयोग तब तक किया जाता है जब तक कि यह एक ऐसी वस्तु न हो जो एक स्थिर अभिव्यक्ति (5.19) में प्रकट होने के लिए आवश्यकताओं को संतुष्ट करता है और अंतराल-से-अंतराल रूपांतरण (4.1) तुरंत लागू होता है।

[basic.def.odr] में।

संपादित करें: जाहिरा तौर पर यह गलत हिस्सा है और पूरे पैराग्राफ में विभिन्न चीजों के लिए कई परिभाषाएं हैं। यह क्लास टेम्पलेट सदस्य फ़ंक्शन के लिए प्रासंगिक हो सकता है:

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

मुझे यह समझ में नहीं आता है कि यह नियम कई संकलन इकाइयों में कैसे काम करता है? यदि मैं स्पष्ट रूप से एक क्लास टेम्पलेट को तत्काल तैयार करता हूं, तो क्या सभी सदस्य कार्य त्वरित रूप से किए जाते हैं?


2
ध्यान दें कि [basic.def.odr] / 6 कक्षा के सदस्य कार्यों के लिए लागू होता है "एक से अधिक परिभाषा हो सकती है [...]"
dyp

3
"यदि मैं स्पष्ट रूप से एक क्लास टेम्पलेट को तुरंत लिखता हूं तो क्या सभी सदस्य कार्य तत्काल होते हैं?" हाँ, देखें [temp.explicit] / 8 + 9
dyp

जवाबों:


72

यह केवल एक मनमानी परिभाषा है, जिसका उपयोग मानक द्वारा निर्दिष्ट करने के लिए किया जाता है जब आपको एक इकाई के लिए परिभाषा प्रदान करनी चाहिए (केवल एक घोषणा के विपरीत)। मानक केवल "उपयोग" नहीं कहता है, क्योंकि यह संदर्भ के आधार पर विविध रूप से व्याख्या की जा सकती है। और कुछ ओडीआर-उपयोग वास्तव में उस चीज के अनुरूप नहीं हैं जो कोई "उपयोग" के साथ जुड़ता है; उदाहरण के लिए, एक वर्चुअल फ़ंक्शन हमेशा ODR-उपयोग किया जाता है जब तक कि यह शुद्ध न हो, भले ही इसे वास्तव में प्रोग्राम में कहीं भी नहीं बुलाया गया हो।

पूर्ण परिभाषा §3.2 में है , दूसरा पैराग्राफ, हालांकि इसमें परिभाषा को पूरा करने के लिए अन्य अनुभागों का संदर्भ है।

टेम्प्लेट के संबंध में, ODR- प्रयुक्त केवल प्रश्न का हिस्सा है; दूसरा हिस्सा तात्कालिकता है। विशेष रूप से, particular14.7 तब शामिल होता है जब कोई टेम्पलेट त्वरित होता है। लेकिन दोनों संबंधित हैं: जबकि two14.7.1 (अंतर्निहित तात्कालिकता) में पाठ काफी लंबा है, मूल सिद्धांत यह है कि इसका उपयोग किए जाने पर एक टेम्पलेट केवल तात्कालिक होगा, और इस संदर्भ में, इसका अर्थ है ODR- प्रयुक्त। इस प्रकार, एक वर्ग टेम्पलेट का एक सदस्य कार्य केवल अगर यह कहा जाता है, या यदि यह आभासी है और वर्ग ही त्वरित है, तो तत्काल किया जाएगा। मानक स्वयं कई स्थानों पर इस पर निर्भर std::list<>::sortकरता है : <व्यक्तिगत तत्वों पर उपयोग , लेकिन आप किसी तत्व प्रकार पर एक सूची को रोक सकते हैं जो समर्थन नहीं करता है <, जब तक आप उस sortपर कॉल नहीं करते हैं ।


क्या ओडीआर-उपयोग "भौतिकवादी अस्थायी" के साथ ओवरलैप कर सकता है?
v.oddou

23

सादे शब्द में, ओड-यूज्ड का मतलब कुछ है (चर या फ़ंक्शन) एक संदर्भ में उपयोग किया जाता है जहां इसकी परिभाषा मौजूद होनी चाहिए।

जैसे,

struct F {
   static const int g_x = 2;
};

int g_x_plus_1 = F::g_x + 1; // in this context, only the value of g_x is needed.
                             // so it's OK without the definition of g_x

vector<int>  vi;
vi.push_back( F::g_x );      // Error, this is odr-used, push_back(const int & t) expect
                             // a const lvalue, so it's definition must be present

ध्यान दें, उपरोक्त पुश_बैक MSVC 2013 में पारित हुआ, यह व्यवहार मानक अनुपालन नहीं है, दोनों gcc 4.8.2 और clang 3.8.0 विफल रहे, त्रुटि संदेश है: अपरिष्कृत संदर्भ `K :: g_x '


क्या vi.push_back( F::g_x );c ++ की तरह स्थिर डेटा सदस्य का उपयोग करना संभव है ?
रंकाबा

लेकिन एक प्रतिद्वंद्विता को भी पारित किया जा सकता है const int&? क्या स्थैतिक सदस्य सदस्य को प्रतिद्वंद्विता के रूप में चिह्नित किया जा सकता है?
स्कैटेक्सियाओ

8
सक्सेस ओपनिंग वाक्य के लिए +1: "सादे शब्द में, ओड-यूज्ड का मतलब है कुछ (चर या फ़ंक्शन) का उपयोग उस संदर्भ में किया जाता है जहां इसकी परिभाषा मौजूद होनी चाहिए।"
पॉल मसरी-स्टोन

1
मुझे समझ नहीं आता कि आप उस कोड को कैसे संकलित करते हैं। क्या वे एक ही टीयू में हैं? यदि वे हैं, तो एफ :: g_x को पहले से ही परिभाषित किया गया है push_back, निश्चित रूप से यह पारित हो जाएगा। है ना?
लेविस चैन

1
@bigxiao " एक अंतराल भी पारित किया जा सकता है " हाँ और एक अस्थायी ऑब्जेक्ट कंपाइलर और उस ऑब्जेक्ट से जुड़े संदर्भ द्वारा बनाया गया है। OTOH जब एक लवल्यू पास होता है जिसका अर्थ उस वस्तु को पास करना है जिसे लैवल्यू के मूल्यांकन द्वारा संदर्भित किया जाता है: जब आप एक लैवल्यू पास करते हैं तो आप फ़ंक्शन में पैरामीटर को सही ऑब्जेक्ट को संदर्भित करने की अपेक्षा कर सकते हैं। संकलक एक अस्थायी नहीं बनाएगा। यदि आप एक अस्थायी चाहते हैं, के साथ एक बनाओ operator+
जिज्ञासु
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.