ইনলাইন নেমস্পেসগুলি কীসের জন্য?


334

সি ++ 11 inline namespaceগুলি এর অনুমতি দেয় , যার সমস্ত সদস্যও স্বয়ংক্রিয়ভাবে ঘেরের মধ্যে রয়েছে namespace। আমি এর কোন কার্যকর প্রয়োগের কথা ভাবতে পারি না - কেউ দয়া করে এমন পরিস্থিতিতে একটি সংক্ষিপ্ত, সংক্ষিপ্ত উদাহরণ দিতে পারেন যেখানে inline namespaceকোনটি প্রয়োজন এবং এটিই সবচেয়ে মূর্তিযুক্ত সমাধান?

(এছাড়াও, আমার কাছে এটি স্পষ্ট নয় যে একটিতে যখন একটি namespaceঘোষণা করা inlineহয় তবে সমস্ত ঘোষণাপত্রে নয়, যা বিভিন্ন ফাইলে থাকতে পারে live এটি কি সমস্যার জন্য ভিক্ষা করছে না?)

উত্তর:


339

ইনলাইন নেমস্পেসগুলি একটি লাইব্রেরির সংস্করণ বৈশিষ্ট্য যা প্রতীক সংস্করণের অনুরূপ , তবে নির্দিষ্ট বাইনারি এক্সিকিউটেবল ফর্ম্যাটের বৈশিষ্ট্য (অর্থাত্ প্ল্যাটফর্ম-নির্দিষ্ট) না হয়ে সি ++ 11 স্তরে (অর্থাত্ ক্রস-প্ল্যাটফর্ম) বিশুদ্ধভাবে প্রয়োগ করা হয়েছে।

এটি এমন একটি প্রক্রিয়া যার মাধ্যমে একটি গ্রন্থাগার লেখক নেস্টেড নেমস্পেস চেহারা তৈরি করতে পারে এবং কাজ করতে পারে যেমন এর সমস্ত ঘোষণাগুলি আশেপাশের নেমস্পেসে ছিল (ইনলাইন নেমস্পেসগুলি নেস্ট করা যেতে পারে, তাই "আরও-নেস্টেড" নামগুলি সর্বপ্রথম অলঙ্কৃত করে -অনলাইন নেমস্পেস এবং চেহারা এবং এমনভাবে কাজ করুন যেন তাদের ঘোষণাপত্রের মধ্যে কোনও নেমস্পেসের মধ্যে থাকে)।

উদাহরণ হিসাবে, এর এসটিএল বাস্তবায়ন বিবেচনা করুন vector। সি ++ এর শুরু থেকে যদি আমাদের ইনলাইন নেমস্পেস থাকে তবে সি ++ 98 এ শিরোনামটি <vector>দেখতে দেখতে এমন হতে পারে:

namespace std {

#if __cplusplus < 1997L // pre-standard C++
    inline
#endif

    namespace pre_cxx_1997 {
        template <class T> __vector_impl; // implementation class
        template <class T> // e.g. w/o allocator argument
        class vector : __vector_impl<T> { // private inheritance
            // ...
        };
    }
#if __cplusplus >= 1997L // C++98/03 or later
                         // (ifdef'ed out b/c it probably uses new language
                         // features that a pre-C++98 compiler would choke on)
#  if __cplusplus == 1997L // C++98/03
    inline
#  endif

    namespace cxx_1997 {

        // std::vector now has an allocator argument
        template <class T, class Alloc=std::allocator<T> >
        class vector : pre_cxx_1997::__vector_impl<T> { // the old impl is still good
            // ...
        };

        // and vector<bool> is special:
        template <class Alloc=std::allocator<bool> >
        class vector<bool> {
            // ...
        };

    };

#endif // C++98/03 or later

} // namespace std

এর মান উপর নির্ভর করে __cplusplus, এক বা অন্য vectorবাস্তবায়ন বেছে নেওয়া হয়। আপনার কোডবেস প্রাক সি ++ 98 বার লেখা হয়েছিল, এবং আপনি যে সি ++ 98 সংস্করণ যদি vectorআপনি আপনার কম্পাইলার আপগ্রেড আপনার জন্য কষ্ট হয় যার ফলে, "সমস্ত" আপনাকে যা করতে হবে উল্লেখ খুঁজে পেতে std::vectorমধ্যে আপনার কোডবেস এবং এগুলি দ্বারা প্রতিস্থাপন std::pre_cxx_1997::vector

পরবর্তী মান এস, STL বিক্রেতা আবার প্রক্রিয়া পুনরাবৃত্তি, এর জন্য একটি নতুন নামস্থান প্রবর্তনের std::vectorসঙ্গে emplace_backসমর্থন (যা সি প্রয়োজন ++, 11) এবং যে এক iff ইনলাইনিং __cplusplus == 201103L

ঠিক আছে, তবে এর জন্য আমার কেন একটি নতুন ভাষার বৈশিষ্ট্য প্রয়োজন? আমি ইতিমধ্যে একই প্রভাব করতে নিম্নলিখিতগুলি করতে পারি, না?

namespace std {

    namespace pre_cxx_1997 {
        // ...
    }
#if __cplusplus < 1997L // pre-standard C++
    using namespace pre_cxx_1997;
#endif

#if __cplusplus >= 1997L // C++98/03 or later
                         // (ifdef'ed out b/c it probably uses new language
                         // features that a pre-C++98 compiler would choke on)

    namespace cxx_1997 {
        // ...
    };
#  if __cplusplus == 1997L // C++98/03
    using namespace cxx_1997;
#  endif

#endif // C++98/03 or later

} // namespace std

এর মানের উপর নির্ভর করে __cplusplusআমি বাস্তবায়নগুলির মধ্যে একটি বা অন্যটি পাই।

এবং আপনি প্রায় সঠিক হতে চাই।

নিম্নলিখিত বৈধ সি ++ 98 ব্যবহারকারীর কোডটি বিবেচনা করুন ( stdইতিমধ্যে সি ++ 98 তে নামস্থানে থাকা টেম্পলেটগুলি সম্পূর্ণরূপে অনুমোদিত করার অনুমতি দেওয়া হয়েছিল ):

// I don't trust my STL vendor to do this optimisation, so force these 
// specializations myself:
namespace std {
    template <>
    class vector<MyType> : my_special_vector<MyType> {
        // ...
    };
    template <>
    class vector<MyOtherType> : my_special_vector<MyOtherType> {
        // ...
    };
    // ...etc...
} // namespace std

এটি পুরোপুরি বৈধ কোড যেখানে ব্যবহারকারী কোনও ধরণের সেটের জন্য ভেক্টরের নিজস্ব প্রয়োগের সরবরাহ করে যেখানে তিনি স্পষ্টতই এসটিএলে (তার অনুলিপি) পাওয়া একটির চেয়ে কার্যকর দক্ষতা জানে।

তবে : কোনও টেমপ্লেট বিশেষীকরণের সময়, আপনাকে এটি যে নাম স্থানটিতে ঘোষণা করা হয়েছিল তেমন করতে হবে The স্ট্যান্ডার্ডটি vectorনামস্থানটিতে এটি ঘোষিত হয়েছে std, তাই ব্যবহারকারী যেখানে সঠিকভাবে প্রকারটি বিশেষায়িত করার প্রত্যাশা করেন।

এই কোডটি একটি অ-সংস্করণযুক্ত নেমস্পেসের সাথে কাজ করে std, বা সি ++ 11 ইনলাইন নেমস্পেস বৈশিষ্ট্যটি ব্যবহার করে তবে ব্যবহৃত সংস্করণ কৌশলটি নয় using namespace <nested>, কারণ এটি বাস্তবায়নের বিশদটি প্রকাশ করে যে সত্যিকারের নামস্থানটি vectorসংজ্ঞায়িত ছিল তা stdসরাসরি নয় ।

অন্যান্য ছিদ্র রয়েছে যার দ্বারা আপনি নেস্টেড নেমস্পেসটি সনাক্ত করতে পারেন (নীচে মন্তব্যগুলি দেখুন), তবে ইনলাইন নেমস্পেসগুলি সেগুলি সমস্ত প্লাগ করে। এবং এটি সব আছে। ভবিষ্যতের জন্য অপরিসীম দরকারী, তবে এএফআইএকি স্ট্যান্ডার্ড নিজস্ব স্ট্যান্ডার্ড লাইব্রেরির জন্য ইনলাইন নেমস্পেসের নামগুলি লিখেনি (যদিও আমি এটির জন্য ভুল প্রমাণিত হতে চাই), তাই এটি কেবল তৃতীয় পক্ষের লাইব্রেরির জন্য ব্যবহার করা যেতে পারে, না মান নিজেই (সংকলক বিক্রেতারা নামকরণের স্কিমের সাথে একমত না হলে)।


23
using namespace V99;স্ট্রস্ট্রপের উদাহরণে কেন কাজ করে না তা ব্যাখ্যা করার জন্য +1 ।
স্টিভ জেসোপ

3
এবং তেমনিভাবে, আমি যদি স্ক্র্যাচ থেকে একেবারে নতুন সি ++ 21 বাস্তবায়ন শুরু করি, তবে আমি পুরানো বাজে কথাগুলি বাস্তবায়নে বোঝা হতে চাই না std::cxx_11। প্রতিটি সংকলক সর্বদা স্ট্যান্ডার্ড লাইব্রেরির সমস্ত পুরানো সংস্করণ বাস্তবায়ন করবে না, যদিও এই মুহুর্তে এটি লোভনীয় মনে করে যে তারা নতুন যুক্ত করার সময় বিদ্যমান বাস্তবায়নগুলি পুরানো অবস্থায় রেখে দেওয়া দরকার, কারণ বাস্তবে তারা সবাই যাইহোক হয়। আমি মনে করি মানকটি কার্যকরভাবে যা করতে পারে তা এটিকে alচ্ছিক করা হয়েছে তবে উপস্থিত থাকলে একটি মানক নাম দিয়ে with
স্টিভ জেসোপ

46
এটি কিছুই নেই। এডিএলও একটি কারণ ছিল (এডিএল নির্দেশাবলী ব্যবহার করে না), এবং নাম অনুসন্ধানও। ( using namespace Aকোনও নেমস্পেস বিতে নামস্পেস বি তে নামগুলি লুকিয়ে রাখে যদি নেমস্পেস এ-তে নামগুলি লুকান B::name- তবে ইনলাইন নেমস্পেসের সাথে নয়)।
জোহানেস স্কাউব - লিটব

4
ifdefসম্পূর্ণ ভেক্টর বাস্তবায়নের জন্য কেন কেবল এস ব্যবহার করবেন না ? সমস্ত বাস্তবায়ন এক নামস্থানে হবে তবে কেবলমাত্র একটির প্রাকপ্রসেসিংয়ের পরে সংজ্ঞা দেওয়া হবে
sasha.sochka

6
@ sasha.sochka, কারণ এই ক্ষেত্রে আপনি অন্য বাস্তবায়ন ব্যবহার করতে পারবেন না। এগুলি প্রিপ্রোসেসর দ্বারা সরানো হবে। ইনলাইন নেমস্পেসের সাহায্যে আপনি পুরোপুরি যোগ্যতাসম্পন্ন নাম (বা usingকীওয়ার্ড) নির্দিষ্ট করে যে কোনও বাস্তবায়ন আপনি ব্যবহার করতে পারেন ।
ভ্যাসিলি বিরিয়ুকভ

70

http://www.stroustrup.com/C++11FAQ.html#inline-namespace (বাজার্ন স্ট্রস্ট্রপ দ্বারা রচিত এবং রক্ষণাবেক্ষণকৃত একটি নথি, যাকে আপনি বেশিরভাগ সি ++ 11 বৈশিষ্ট্যের জন্য সর্বাধিক অনুপ্রেরণাগুলি সম্পর্কে সচেতন হওয়া উচিত বলে মনে করেন। )

তার মতে, এটি পশ্চাদপদ-সামঞ্জস্যের জন্য সংস্করণটির অনুমতি দেওয়া। আপনি একাধিক অভ্যন্তরীণ নেমস্পেসগুলি সংজ্ঞায়িত করেছেন এবং সর্বাধিক সাম্প্রতিক একটি তৈরি করেছেন inline। বা যাইহোক, সংস্করণে যত্ন নেই এমন লোকদের জন্য ডিফল্ট। আমি মনে করি সবচেয়ে সাম্প্রতিকতম কোনও ভবিষ্যতের বা কাটিয়া প্রান্তের সংস্করণ হতে পারে যা এখনও ডিফল্ট নয়।

প্রদত্ত উদাহরণটি হ'ল:

// file V99.h:
inline namespace V99 {
    void f(int);    // does something better than the V98 version
    void f(double); // new feature
    // ...
}

// file V98.h:
namespace V98 {
    void f(int);    // does something
    // ...
}

// file Mine.h:
namespace Mine {
#include "V99.h"
#include "V98.h"
}

#include "Mine.h"
using namespace Mine;
// ...
V98::f(1);  // old version
V99::f(1);  // new version
f(1);       // default version

আপনি কেন স্থানের using namespace V99;ভিতরে রাখেন না তা তাত্ক্ষণিকভাবে আমি দেখতে পাই না Mine, তবে কমিটির অনুপ্রেরণায় বর্জনের শব্দটির জন্য এটি ব্যবহারের ক্ষেত্রে পুরোপুরি বুঝতে হবে না।


সুতরাং আসলে শেষ f(1)সংস্করণটি ইনলাইন V99নেমস্পেস থেকে ডাকা হবে ?
ইটান টি

1
@ আইটানটি: হ্যাঁ, কারণ বিশ্বব্যাপী নেমস্পেস রয়েছে using namespace Mine;এবং Mineনেমস্পেসে ইনলাইন নেমস্পেস থেকে সমস্ত কিছু রয়েছে Mine::V99
স্টিভ জেসোপ

2
@ ওয়াল্টার: আপনি অন্তর্ভুক্ত রিলিজের inlineফাইল থেকে সরান । আপনি অতিরিক্ত একইসাথে যুক্ত করতে অবশ্যই একই সময়ে সংশোধন করতে পারেন। গ্রন্থাগারের অংশ, ক্লায়েন্ট কোডের অংশ নয়। V99.hV100.hMine.hMine.h
স্টিভ জেসোপ

5
@ ওয়াল্টার: তারা ইনস্টল করছে না V100.h, তারা "মাইন" নামে একটি লাইব্রেরি ইনস্টল করছে। - "খনি" সংস্করণ 99 3 হেডার ফাইল নেই Mine.h, V98.hএবং V99.h। - "খনি" সংস্করণ 100 4 হেডার ফাইল নেই Mine.h, V98.h, V99.hএবং V100.h। শিরোনাম ফাইলগুলির বিন্যাস হ'ল একটি বাস্তবায়ন বিশদ যা ব্যবহারকারীদের কাছে অপ্রাসঙ্গিক। যদি তারা কিছু সামঞ্জস্যতা সমস্যা আবিষ্কার করে যার অর্থ তাদের Mine::V98::fকিছু বা সমস্ত কোড থেকে বিশেষত ব্যবহার করা প্রয়োজন , তারা Mine::V98::fপুরানো কোড থেকে কলগুলিকে Mine::fসদ্য-লিখিত কোডগুলিতে কল মিশ্রিত করতে পারে ।
স্টিভ জেসোপ

2
@ ওয়াল্টার অন্যান্য উত্তরের উল্লেখ অনুসারে, টেমপ্লেটগুলিকে যে নাম-স্থানে ঘোষিত করা হয়েছে তেমন কোনও নির্দিষ্ট স্থান ব্যবহার করে নয়, নাম-স্পেসে বিশেষীকরণ করা দরকার While যদিও এটি অদ্ভুত দেখাচ্ছে, সেখানে এটি যেভাবে হয়েছে সেখানে আপনাকে টেমপ্লেটগুলি বিশেষায়িত করার অনুমতি দেয় Mineপরিবর্তে, বিশেষায়িত হওয়া Mine::V99বা Mine::V98
জাস্টিন সময় - মনিকা

8

অন্যান্য সমস্ত উত্তর ছাড়াও।

প্রতীকগুলিতে এবিআই তথ্য বা ফাংশনের সংস্করণ এনকোড করতে ইনলাইন নেমস্পেস ব্যবহার করা যেতে পারে। এটি এই কারণে পশ্চাদপদ এবিআইয়ের সামঞ্জস্যতা সরবরাহ করতে ব্যবহৃত হয়। ইনলাইন নেমস্পেসগুলি আপনাকে এপিআই পরিবর্তন না করে ম্যাংলেড নাম (এবিআই) তে তথ্য ইনজেক্ট করতে দেয় কারণ তারা কেবলমাত্র লিঙ্কারের প্রতীক নামকেই প্রভাবিত করে।

এই উদাহরণ বিবেচনা করুন:

ধরুন আপনি কোনও ফাংশন লিখেছেন Fooযা কোনও অবজেক্টের রেফারেন্স নিয়ে বলে barএবং কিছুই দেয়নি।

মেইন.পি.পি. তে বলুন

struct bar;
void Foo(bar& ref);

যদি আপনি এই ফাইলটিকে কোনও বস্তুতে সংকলনের পরে আপনার প্রতীক নামটি পরীক্ষা করেন।

$ nm main.o
T__ Z1fooRK6bar 

লিঙ্কারের প্রতীক নামটি ভিন্ন হতে পারে তবে এটি অবশ্যই ফাংশন এবং যুক্তির ধরণের নাম কোথাও এনকোড করবে।

এখন, এটি যে barহিসাবে সংজ্ঞায়িত করা যেতে পারে :

struct bar{
   int x;
#ifndef NDEBUG
   int y;
#endif
};

বিল্ড প্রকারের উপর নির্ভর করে barএকই লিঙ্কার প্রতীক সহ দুটি ভিন্ন ধরণের / লেআউট উল্লেখ করতে পারে।

এই জাতীয় আচরণ রোধ করতে আমরা আমাদের কাঠামোটিকে barএকটি ইনলাইন নেমস্পেসে আবদ্ধ করি, যেখানে বিল্ডের উপর নির্ভর করে লিঙ্কার চিহ্নটি barআলাদা হবে।

সুতরাং, আমরা লিখতে পারে:

#ifndef NDEBUG
inline namespace rel { 
#else
inline namespace dbg {
#endif
struct bar{
   int x;
#ifndef NDEBUG
   int y;
#endif
};
}

এখন আপনি যদি প্রতিটি অবজেক্টের অবজেক্ট ফাইলটি দেখেন তবে আপনি একটি রিলিজ ব্যবহার করে তৈরি করেন এবং অন্যটি ডিবাগ পতাকা সহ। আপনি দেখতে পাবেন যে লিঙ্কার চিহ্নগুলিতে ইনলাইন নেমস্পেসের নামও অন্তর্ভুক্ত রয়েছে। এক্ষেত্রে

$ nm rel.o
T__ ZROKfoo9relEbar
$ nm dbg.o
T__ ZROKfoo9dbgEbar

লিঙ্কারের প্রতীকগুলির নাম আলাদা হতে পারে be

প্রতীক নামের উপস্থিতি relএবং উপস্থিতি লক্ষ্য করুন dbg

এখন, আপনি যদি রিলিজ মোড বা ভাইস-বিপরীতে ডিবাগকে লিঙ্ক করার চেষ্টা করেন তবে রানটাইম ত্রুটির বিপরীতে লিঙ্কারের ত্রুটি পাবেন।


1
হ্যাঁ, এটা বোঝা যায়। সুতরাং এটি লাইব্রেরি প্রয়োগকারী এবং এর মতো আরও বেশি।
ওয়াল্টার

3

আমি আসলে ইনলাইন নেমস্পেসের জন্য আরেকটি ব্যবহার আবিষ্কার করেছি।

সঙ্গে কিউটি , আপনি কিছু অতিরিক্ত পেতে, চমৎকার ব্যবহার অতিরিক্ত বৈশিষ্ট্যগুলিও উপস্থিত রয়েছে Q_ENUM_NS, ঘুরে প্রয়োজন যা এনক্লোজিং নামস্থান একটি মেটা-বস্তু, যা দিয়ে ঘোষিত হয় যে Q_NAMESPACE। যাইহোক, Q_ENUM_NSকাজ করার জন্য , Q_NAMESPACE একই ফাইলটিতে একটি অনুরূপ থাকতে হবে ⁽¹⁾ এবং শুধুমাত্র একটি থাকতে পারে, বা আপনি সদৃশ সংজ্ঞা ত্রুটি পেতে পারেন। এটি কার্যকরভাবে এর অর্থ হল যে আপনার সমস্ত গণনা একই শিরোনামে থাকা উচিত। ইশ।

বা ... আপনি ইনলাইন নেমস্পেস ব্যবহার করতে পারেন। inline namespaceঅতিরিক্ত নেমস্পেসের মতো ব্যবহারকারীর দিকে তাকানোর সময় কোনও অঙ্কে অঙ্কগুলিগোপন করারকারণে মেটা-অবজেক্টগুলির বিভিন্ন ম্যাঙ্গেল নাম রয়েছে ⁽²⁾

তাই, তারা একাধিক উপ-নামব্যবধান মধ্যে বিভাজন কাপড় জন্য দরকারী করছি যে সব বর্ণন এক নামস্থান মতো, আপনি কোনো কারণে যে কি করতে হবে পারেন। অবশ্যই using namespace innerএটি বাইরের নেমস্পেসে লেখার অনুরূপ তবে ডিআরওয়াই লঙ্ঘন না করে অভ্যন্তরীণ নেমস্পেসের নামটি দু'বার লেখার ব্যপারে


  1. এটি আসলে এর চেয়ে খারাপ; এটি ধনুর্বন্ধনী একই সেট হতে হবে।

  2. আপনি মেটা-অবজেক্টটিকে সম্পূর্ণরূপে যোগ্যতা ছাড়াই অ্যাক্সেস করার চেষ্টা না করা থাকলেও মেটা-অবজেক্টটি খুব সহজেই সরাসরি ব্যবহার করা হয় না।


আপনি কোডের একটি কঙ্কাল দিয়ে স্কেচ করতে পারেন? (আদর্শভাবে ডাব্লু / ও কিউটির স্পষ্ট উল্লেখ)। এটি সমস্তই বরং জড়িত / অস্পষ্ট শোনায়।
ওয়াল্টার

সহজেই নয় ... পৃথক নেমস্পেসের যে কারণ প্রয়োজন তা কিউটি বাস্তবায়নের বিশদ সাথে সম্পর্কিত। টিবিএইচ, কিউটিটির বাইরের এমন পরিস্থিতি কল্পনা করা শক্ত, যার একই প্রয়োজনীয়তা থাকবে। তবে, এই কিউটি-নির্দিষ্ট দৃশ্যের জন্য, তারা উপকারী! উদাহরণস্বরূপ gist.github.com/mwoehlke-kitware/… বা github.com/Kitware/seal-tk/pull/45 দেখুন ।
ম্যাথু

0

সুতরাং মূল পয়েন্টগুলি সংক্ষেপে বলা যায় using namespace v99এবং inline namespaceএকই ছিল না, সি ++ 11-তে একটি ডেডিকেটেড কীওয়ার্ড (ইনলাইন) প্রবর্তনের আগে সংস্করণ গ্রন্থাগারগুলির পূর্ববর্তী কাজ ছিল যা usingএকই সংস্করণ কার্যকারিতা সরবরাহ করার সময় ব্যবহারের সমস্যাগুলি স্থির করে । ব্যবহার করা using namespaceADL সঙ্গে কারণ সমস্যার করার জন্য ব্যবহৃত (ADL এখন অনুসরণ মনে হচ্ছে যদিও usingনির্দেশনা), এবং আউট-অফ-লাইন একটি লাইব্রেরি বর্গ / ফাংশনের বিশেষজ্ঞতা ইত্যাদি ব্যবহারকারী দ্বারা যদি সত্যি নামস্থান টি সম্পন্ন হয়েছে বাহিরে (যার নাম হবে কাজ না ব্যবহারকারীর জানতে হবে না এবং জানা উচিত নয়, অর্থাত্ ব্যবহারকারীকে সমাধান করতে বিশেষায়নের জন্য কেবল বি :: এর চেয়ে বি :: অবি_ভি 2 :: ব্যবহার করতে হবে)।

//library code
namespace B { //library name the user knows
    namespace A { //ABI version the user doesn't know about
        template<class T> class myclass{int a;};
    }
    using namespace A; //pre inline-namespace versioning trick
} 

// user code
namespace B { //user thinks the library uses this namespace
    template<> class myclass<int> {};
}

এটি স্থিতিশীল বিশ্লেষণের সতর্কতা প্রদর্শন করবে first declaration of class template specialization of 'myclass' outside namespace 'A' is a C++11 extension [-Wc++11-extensions]। তবে আপনি যদি নেমস্পেস এ ইনলাইন করেন তবে সংকলকটি বিশেষতাকে সমাধান করে। যদিও, সি ++ 11 এক্সটেনশন সহ, সমস্যাটি চলে যায়।

বহির্মুখী সংজ্ঞাগুলি ব্যবহার করার সময় সমাধান হয় না using; এগুলি একটি নেস্টেড / অ-নেস্টেড এক্সটেনশন নেমস্পেস ব্লকে ঘোষণা করতে হবে (যার অর্থ ব্যবহারকারীকে আবারও এবিআই সংস্করণটি জানতে হবে, যদি কোনও কারণে তাদের কোনও ক্রিয়াকলাপের নিজস্ব বাস্তবায়ন দেওয়ার অনুমতি দেওয়া হয়েছিল)।

#include <iostream>
namespace A {
    namespace B{
        int a;
        int func(int a);
        template<class T> class myclass{int a;};
        class C;
        extern int d;
    } 
    using namespace B;
} 
int A::d = 3; //No member named 'd' in namespace A
class A::C {int a;}; //no class named 'C' in namespace 'A' 
template<> class A::myclass<int> {}; // works; specialisation is not an out-of-line definition of a declaration
int A::func(int a){return a;}; //out-of-line definition of 'func' does not match any declaration in namespace 'A'
namespace A { int func(int a){return a;};} //works
int main() {
    A::a =1; // works; not an out-of-line definition
}

বি ইনলাইন করার সময় বিষয়টি চলে যায়।

অন্যান্য কার্যকারিতা inlineনেমস্পেসগুলি গ্রন্থাগার লেখককে লাইব্রেরিতে স্বচ্ছ আপডেট সরবরাহের অনুমতি দিচ্ছে 1) ব্যবহারকারীকে নতুন নেমস্পেসের নাম দিয়ে রিফ্যাক্টর কোডটি চাপিয়ে না দিয়ে এবং 2) ভার্বোসটির অভাব রোধ করা এবং 3) এপিআই-অপ্রাসঙ্গিক বিবরণের বিমূর্ততা সরবরাহ করে, যদিও 4) একই উপকারী লিঙ্কার ডায়াগোনস্টিকস এবং আচরণ দেওয়া যা একটি অন-ইনলাইন নেমস্পেস ব্যবহার করে। ধরা যাক আপনি একটি লাইব্রেরি ব্যবহার করছেন:

namespace library {
    inline namespace abi_v1 {
        class foo {
        } 
    }
}

এটি ব্যবহারকারীকে library::fooডকুমেন্টেশনে এবিআই সংস্করণটি জানা বা অন্তর্ভুক্ত না করে কল করার অনুমতি দেয় যা দেখতে আরও পরিষ্কার দেখাচ্ছে। ব্যবহার library::abiverison129389123::fooনোংরা লাগবে।

যখন কোনও আপডেট করা হয় foo, অর্থাৎ ক্লাসে কোনও নতুন সদস্য যুক্ত করা হয়, এটি এপিআই স্তরে বিদ্যমান প্রোগ্রামগুলিকে প্রভাবিত করবে না কারণ তারা ইতিমধ্যে সদস্যটি ব্যবহার করবে না এবং ইনলাইন নেমস্পেসের নাম পরিবর্তন করে এপিআই স্তরে কোনও পরিবর্তন হবে না কারণ library::fooএখনও কাজ করবে।

namespace library {
    inline namespace abi_v2 {
        class foo {
            //new member
        } 
    }
}

যাইহোক, প্রোগ্রামগুলির সাথে এটি লিঙ্ক করে, কারণ ইনলাইন নেমস্পেসের নামটি নিয়মিত নেমস্পেসের মতো প্রতীক নামগুলিতে মঙ্গল করা থাকে, পরিবর্তন লিঙ্কারের পক্ষে স্বচ্ছ হবে না। সুতরাং, যদি অ্যাপ্লিকেশনটি পুনরায় সংযুক্ত না করা হয় তবে এটি লাইব্রেরির একটি নতুন সংস্করণের সাথে সংযুক্ত করা হয় তবে এটি প্রতীকটি উপস্থিতির abi_v1সাথে সংযুক্তি এবং এটিবিআইয়ের অসামঞ্জস্যতার কারণে রানটাইমটিতে একটি রহস্যজনক যুক্তি ত্রুটি সৃষ্টি করার পরিবর্তে ত্রুটি না পাওয়া প্রতীক উপস্থিত করবে । একটি নতুন সদস্য যুক্ত করা টাইপ সংজ্ঞা পরিবর্তনের কারণে ABI সামঞ্জস্যের কারণ হতে পারে, যদিও এটি সংকলন সময়ে (এপিআই স্তর) প্রোগ্রামকে প্রভাবিত করে না।

এই পরিস্থিতিতে:

namespace library {
    namespace abi_v1 {
        class foo {
        } 
    }

    inline namespace abi_v2 {
        class foo {
            //new member
        } 
    }
}

২ টি নন-ইনলাইন নেমস্পেস ব্যবহার করার মতো, এটি অ্যাপ্লিকেশনটি পুনরায় সংকলনের প্রয়োজন ছাড়াই লাইব্রেরির একটি নতুন সংস্করণকে সংযুক্ত করার অনুমতি দেয়, কারণ abi_v1এটি একটি বৈশ্বিক প্রতীকগুলিতে ম্যাঙ্গেল হবে এবং এটি সঠিক (পুরানো) ধরণের সংজ্ঞা ব্যবহার করবে। অ্যাপ্লিকেশনটি পুনরায় সংবিধানের কারণে রেফারেন্সগুলিতে সমাধান হবে library::abi_v2

ব্যবহার using namespaceকরা ব্যবহারের চেয়ে কম কার্যকরী inline(এতে লাইন সংজ্ঞাগুলির বাইরে সমাধান হয় না) তবে উপরের মত একই 4 টি সুবিধা সরবরাহ করে। তবে আসল প্রশ্নটি হ'ল কেন এখন যখন কোনও ডেডিকেটেড কীওয়ার্ডটি করার জন্য এটি বিশদ ব্যবহার করা চালিয়ে যান। এটি ভাল অনুশীলন, কম ভার্বোজ (2 এর পরিবর্তে 1 লাইন কোডের পরিবর্তন করতে হবে) এবং উদ্দেশ্যটি পরিষ্কার করে তোলে।

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.