मॉड्यूल इंटरफेस में इनलाइन अर्थ


24

हेडर फ़ाइल पर विचार करें:

class T
{
private:
  int const ID;

public:
  explicit T(int const ID_) noexcept : ID(ID_) {}

  int GetID() const noexcept { return ID; }
};

या, वैकल्पिक रूप से:

class T
{
private:
  int const ID;

public:
  explicit T(int const ID_) noexcept;

  int GetID() const noexcept;
};

inline T::T(int const ID_) noexcept : ID(ID_) {}

inline int T::GetID() const noexcept { return ID; }

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

बैठक की हालिया रिपोर्ट में जहां C ++ 20 समाप्त हो गया था, मैं निम्नलिखित कथन पढ़ सकता था:

हमने inlineमॉड्यूल इंटरफेस के अर्थ को स्पष्ट किया : आशय यह है कि फ़ंक्शन के निकाय जिन्हें स्पष्ट रूप से घोषित inlineनहीं किया गया है, वे मॉड्यूल के ABI का हिस्सा नहीं हैं, भले ही उन फ़ंक्शन बॉडीज मॉड्यूल इंटरफ़ेस में दिखाई दें। मॉड्यूल लेखकों को अपने एबीआई पर अधिक नियंत्रण देने के लिए, मॉड्यूल इंटरफेस में वर्ग निकायों में परिभाषित सदस्य फ़ंक्शन अब अंतर्निहित नहीं हैं inline

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

यदि हां, तो निम्न मॉड्यूल इंटरफ़ेस ऊपर हेडर के बराबर होगा?

export module M;

export
class T
{
private:
  int const ID;

public:
  inline explicit T(int const ID_) noexcept : ID(ID_) {}

  inline int GetID() const noexcept { return ID; }
};

भले ही मेरे पास अभी भी मॉड्यूल समर्थन के साथ एक कंपाइलर नहीं है, मैं inlineभविष्य में रीफैक्टरिंग को कम करने के लिए, उचित होने पर उपयोग करना शुरू करूंगा ।

जवाबों:


11

इसका मतलब यह है कि, एक मॉड्यूल दुनिया में, कंपाइलर दूर फ़ंक्शन कॉल का अनुकूलन करने में सक्षम होने के लिए हमें उन्हें एनोटेट करना होगा, inlineभले ही वे कक्षा में परिभाषित हों?

कुछ हद तक।

Inlining एक "के रूप में अगर" अनुकूलन है, और inlining अनुवाद इकाइयों के बीच भी हो सकता है अगर कंपाइलर पर्याप्त चालाक है।

यह कहा जा रहा है, एक अनुवाद इकाई के भीतर काम करते समय इनलाइनिंग सबसे आसान है। इस प्रकार, आसान inlineinlining को बढ़ावा देने के लिए, एक -declared फ़ंक्शन को किसी भी अनुवाद इकाई में प्रदान की गई परिभाषा है जहां इसका उपयोग किया जाता है। इसका मतलब यह नहीं है कि कंपाइलर निश्चित रूप से इसे इनलाइन करेगा (या निश्चित रूप से किसी भी गैर- inlineइनक्वालिफ़ाइड फ़ंक्शन को इनलाइन नहीं करेगा), लेकिन यह इनलाइनिंग प्रक्रिया पर चीजों को बहुत आसान बना देता है, क्योंकि इनलाइनिंग उनके बीच के बजाय एक टीयू के भीतर हो रही है।

एक पूर्व-मॉड्यूल दुनिया में एक वर्ग के भीतर परिभाषित कक्षा सदस्य परिभाषाएं inlineस्पष्ट रूप से घोषित की जाती हैं । क्यों? क्योंकि परिभाषा वर्ग के भीतर है। एक पूर्व-मॉड्यूल दुनिया में, टीयू के बीच साझा की जाने वाली कक्षा की परिभाषाएं पाठीय समावेश द्वारा साझा की जाती हैं। एक वर्ग में परिभाषित सदस्यों को इसलिए उन टीयू के बीच साझा किए गए हेडर में परिभाषित किया जाएगा। इसलिए यदि कई टीयू एक ही क्लास का उपयोग करते हैं, तो वे कई टीयू क्लास परिभाषा और हेडर में घोषित उसके सदस्यों की परिभाषा को शामिल करके कर रहे हैं।

यही है, आप वैसे भी परिभाषा को शामिल कर रहे हैं , तो इसे क्यों न बनाएं inline?

बेशक, इसका मतलब है कि एक फ़ंक्शन की परिभाषा अब कक्षा के पाठ का एक हिस्सा है। यदि आप हेडर में घोषित सदस्य की परिभाषा को बदलते हैं, तो यह उस हेडर के प्रत्येक फ़ाइल के पुनर्संरचना को बाध्य करता है, जिसमें वह पुन: शामिल होता है। यहां तक ​​कि अगर वर्ग का इंटरफ़ेस ही नहीं बदल रहा है, तो भी आपको एक recompile करने की आवश्यकता है। इसलिए इस तरह के कार्य करने से inlineयह बदल नहीं जाता है, इसलिए आप ऐसा कर सकते हैं।

पूर्व-मॉड्यूल दुनिया में इससे बचने के लिए, आप केवल C ++ फ़ाइल में सदस्य को परिभाषित कर सकते हैं, जो अन्य फ़ाइलों में शामिल नहीं होगा। आप आसान इनलाइनिंग खो देते हैं, लेकिन आप संकलन-समय प्राप्त करते हैं।

लेकिन यहाँ एक बात है: यह कई स्थानों पर एक कक्षा को वितरित करने के साधन के रूप में शाब्दिक समावेश का उपयोग करने की एक कला है।

एक मॉड्यूलर दुनिया में, आप शायद कक्षा के भीतर प्रत्येक सदस्य फ़ंक्शन को परिभाषित करना चाहते हैं, जैसा कि हम जावा, सी #, पायथन और जैसी अन्य भाषाओं में देखते हैं। यह कोड इलाके को उचित रखता है, और यह एक ही फ़ंक्शन हस्ताक्षर को फिर से टाइप करने से रोकता है, इस प्रकार DRY की जरूरतों को पूरा करता है।

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

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


8

यह P1779 से आता है , जिसे कुछ दिनों पहले प्राग में अपनाया गया था। प्रस्ताव से:

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

कागज (अन्य बातों के अलावा) ने वाक्य को हटा दिया:

एक वर्ग परिभाषा के भीतर परिभाषित एक फ़ंक्शन एक इनलाइन फ़ंक्शन है।

और वाक्य जोड़ा:

वैश्विक मॉड्यूल में, वर्ग परिभाषा के भीतर परिभाषित एक फ़ंक्शन अंतर्निहित रूप से इनलाइन ([class.mfct], [class.friend]) है।


आपका उदाहरण export module Mप्रारंभिक कार्यक्रम के मॉड्यूलर समकक्ष होगा। ध्यान दें कि संकलक पहले से ही इनलाइन फ़ंक्शंस करते हैं inline, जो एनोटेट नहीं हैं , यह सिर्फ इतना है कि वे अतिरिक्त रूप inlineसे अपने उत्तराधिकार में कीवर्ड की उपस्थिति का उपयोग करते हैं।


तो, inlineकीवर्ड के बिना मॉड्यूल में एक फ़ंक्शन कंपाइलर द्वारा कभी भी इनलेट नहीं किया जाएगा, सही?
मेटलफॉक्स

1
@metalfox नहीं, मुझे विश्वास नहीं है कि यह सही है।
बैरी

1
समझा। धन्यवाद। यह वैसा ही है जैसा कि इसे cpp फ़ाइल में परिभाषित किया गया था, जिसका अर्थ यह नहीं है कि यह लिंक समय पर इनलेट नहीं किया जाएगा।
मेटलफॉक्स
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.