क्या हेडर के भीतर C ++ में नेस्टेड नेमस्पेस को व्यक्त करने का एक बेहतर तरीका है


97

मैंने C ++ से जावा और C # में स्विच किया और मुझे लगता है कि नामस्थान / पैकेज का उपयोग वहाँ बेहतर है (अच्छी तरह से संरचित)। फिर मैं C ++ पर वापस आया और उसी तरह नामस्थानों का उपयोग करने की कोशिश की, लेकिन आवश्यक सिंटैक्स शीर्षलेख फ़ाइल के भीतर भयानक है।

namespace MyCompany
{
    namespace MyModule
    {
        namespace MyModulePart //e.g. Input
        {
            namespace MySubModulePart
            {
                namespace ...
                {
                    public class MyClass    

निम्नलिखित मुझे भी अजीब लगता है (गहरे इंडेंट से बचने के लिए):

namespace MyCompany
{
namespace MyModule
{
namespace MyModulePart //e.g. Input
{
namespace MySubModulePart
{
namespace ...
{
     public class MyClass
     {

क्या उपरोक्त चीज़ को व्यक्त करने का एक छोटा तरीका है? मुझे कुछ याद आ रहा है

namespace MyCompany::MyModule::MyModulePart::...
{
   public class MyClass

अपडेट करें

ठीक है, कुछ लोग कहते हैं कि जावा / सी # और सी ++ में उपयोग की अवधारणा अलग है। वास्तव में? मुझे लगता है कि (गतिशील) वर्ग लोडिंग केवल नामस्थान (यह एक बहुत ही तकनीकी तर्कपूर्ण परिप्रेक्ष्य है) के लिए एकमात्र उद्देश्य नहीं है। मुझे इसे पठनीयता और संरचनाकरण के लिए क्यों नहीं इस्तेमाल करना चाहिए, उदाहरण के लिए "इंटेलीजेंसी" के बारे में सोचें।

वर्तमान में, किसी नाम स्थान के बीच कोई तर्क / गोंद नहीं है और आप वहां क्या पा सकते हैं। जावा और C # यह बहुत बेहतर करता है ... क्यों <iostream>और इसमें नामस्थान शामिल हैं std? ठीक है, अगर आप कहते हैं कि तर्क हेडर पर भरोसा करना चाहिए शामिल करने के लिए, क्यों # शामिल की तरह एक "IntelliSense 'दोस्ताना सिंटैक्स का उपयोग करता नहीं करता है #include <std::io::stream>या <std/io/stream>? मुझे लगता है कि जावा / C # की तुलना में डिफ़ॉल्ट लिबास में लापता संरचनावाद C ++ की कमजोरी है।

यदि संघर्षों से निपटने की विशिष्टता एक बिंदु है (जो कि सी # और जावा का एक बिंदु है, तो भी) एक अच्छा विचार यह है कि प्रोजेक्ट नाम या कंपनी के नाम को नामस्थान के रूप में उपयोग करें, क्या आपको ऐसा नहीं लगता है?

एक तरफ यह कहा जाता है कि सी ++ सबसे अधिक लचीला है ... लेकिन सभी ने कहा "ऐसा नहीं करते"? ऐसा लगता है कि C ++ कई काम कर सकता है लेकिन C # की तुलना में कई मामलों में सबसे आसान चीजों के लिए भी एक भयानक सिंटैक्स है।

अपडेट २

अधिकांश उपयोगकर्ता कहते हैं कि दो स्तरों से अधिक गहरा घोंसला बनाना बकवास है। ठीक है, तो विंडोज के बारे में क्या :: UI :: Xaml और विंडोज :: UI :: Xaml :: नियंत्रण :: विजेता के विकास में नाम स्थान? मुझे लगता है कि Microsoft नामस्थानों का उपयोग समझ में आता है और यह वास्तव में सिर्फ 2 स्तरों से अधिक गहरा है। मुझे लगता है कि बड़े पुस्तकालयों / परियोजनाओं के लिए एक गहन घोंसले के शिकार की आवश्यकता है (मुझे एक्स्ट्रालांग क्लैसमनैमेबेक्यूएट टेवरीइंसिंग इनइमनाम नामस्थान जैसे वर्ग नामों से नफरत है ... तो आप वैश्विक नेमस्पेस में भी सब कुछ डाल सकते हैं।

अपडेट 3 - निष्कर्ष

ज्यादातर कहते हैं कि "ऐसा मत करो", लेकिन ... यहां तक ​​कि बढ़ावा एक गहरी घोंसले के शिकार है तो एक या दो स्तरों। हाँ, यह एक पुस्तकालय है लेकिन: यदि आप पुन: प्रयोज्य कोड चाहते हैं - अपने स्वयं के कोड के साथ एक पुस्तकालय की तरह व्यवहार करें जो आप किसी और को देंगे। मैं नाम स्थान का उपयोग करते हुए डिस्कवरी उद्देश्यों के लिए एक गहरी नेस्टिंग का भी उपयोग करता हूं।


3
क्या यह namespaceकीवर्ड का दुरुपयोग है ?
नवाज

4
namepaces और c # / java मॉड्यूल सिस्टम एक ही उद्देश्य की सेवा नहीं करते हैं, जैसे कि आपको उन्हें उसी तरह इस्तेमाल करने की कोशिश नहीं करनी चाहिए। और नहीं, कोई सरल वाक्यविन्यास नहीं है, बस बीक्युस का कोई मतलब नहीं है कि चीजों को आसान बनाने के लिए एक वाक्यविन्यास प्रदान करने का कोई मतलब नहीं है, जो कि करने के लिए नहीं है।
प्लाज्माएचएच

@PlasmaHH ... तो कमजोरी C ++ के std lib का लापता संरचनाकरण है? (अद्यतन के भीतर मेरे सरल उदाहरण देखें)
समुद्र तट

@ सटेगी: यदि आप ध्वनि तर्क दे सकते हैं कि यह क्यों गायब है, और इस तरह के संरचनात्मककरण से हमें क्या ठोस लाभ मिलेंगे, तो हम संभावित कमजोरियों के बारे में बात कर सकते हैं। तब तक मैं सबसे अच्छा भ्रामक संकुल के अंतहीन अंतहीन घोंसले को बुलाऊंगा।
प्लाज़्मा एचएच

3
@PlasmaHH Intellisense और हेडर (पैकेज) शामिल किए जाने के बाद / अन्य सहायकों के लिए। एक कंपनी के भीतर बड़ी परियोजनाओं को एक स्पष्ट विवरण के लिए एक नेस्टिंग (उदाहरण के लिए vw :: golflib :: io) से अधिक की आवश्यकता हो सकती है, जिसमें एक नाम स्थान "स्कोप" होता है। ठीक है, आप बस vw का उपयोग कर सकते हैं :: लेकिन अगर नाम स्थान का उपयोग संघर्ष से बचने के लिए किया जाता है, तो घोषित करने के लिए इतना भयानक क्यों हैं? यह इस बिंदु पर समाप्त होता है कि कोई भी इसका उपयोग नहीं करता है या केवल एक की गहराई के साथ नेमस्पेस का उपयोग करता है (जैसा कि अक्सर सुझाव दिया जाता है)।
Beachwalker

जवाबों:


130

C ++ 17 नेस्टेड नेमस्पेस परिभाषा को सरल कर सकता है:

namespace A::B::C {
}

के बराबर है

namespace A { namespace B { namespace C {
} } }

Cppreference पर नाम स्थान पृष्ठ पर देखें (8):
http://en.cppreference.com/w/cpp/language/namespace


5
... संकलक स्विच द्वारा सक्षम/std:c++latest
धूप चंद्रमा

3
ध्यान दें, कि यदि आप /std:c++latestVisual Studio 2015 में उपयोग करेंगे और Boost का उपयोग भी करेंगे, तो कुछ Boost हेडर को शामिल करने पर आप बहुत रहस्यमय कंपाइलर त्रुटियों का सामना कर सकते हैं। मुझे इस समस्या का सामना करना पड़ा जैसा कि इस
स्टैकऑवरफ्लो

1
यह के रूप में काम करता है, नामस्थान A :: B :: C। मैंने
ervinbosenbacher

30

वास्तव में गहरी इंडेंटिंग से बचने के लिए, मैं आमतौर पर इस तरह से करता हूं:

namespace A { namespace B { namespace C
{
    class X
    {
        // ...
    };
}}}

2
JFYI clang-formatस्वरूपित नहीं कर सकता है कि जैसा कि आप दिखा रहे हैं clang.llvm.org/docs/ClangFormatStyleOptions.html (NamespaceIndentation)
KindDragon

17

मैं पीटरचेन के उत्तर का पूरी तरह से समर्थन करता हूं, लेकिन कुछ ऐसा जोड़ना चाहता हूं जो आपके प्रश्न के दूसरे हिस्से को संबोधित करे।

नाम स्थान की घोषणा करना C ++ में बहुत दुर्लभ मामलों में से एक है, जहां मैं वास्तव में #defineएस के उपयोग को पसंद करता हूं ।

#define MY_COMPANY_BEGIN  namespace MyCompany { // begin of the MyCompany namespace
#define MY_COMPANY_END    }                     // end of the MyCompany namespace
#define MY_LIBRARY_BEGIN  namespace MyLibrary { // begin of the MyLibrary namespace
#define MY_LIBRARY_END    }                     // end of the MyLibrary namespace

यह नेमस्पेस के समापन ब्रेस के पास टिप्पणियों की आवश्यकता को भी हटाता है (क्या आपने कभी किसी बड़े स्रोत फ़ाइल के नीचे स्क्रॉल किया है और / ब्रेसिज़ को जोड़ने / हटाने की कोशिश की थी जो अनुपलब्ध टिप्पणियां थीं जिनके बारे में ब्रेस कौन सी गुंजाइश बंद करता है? ।)।

MY_COMPANY_BEGIN
MY_LIBRARY_BEGIN

class X { };

class Y { };

MY_LIBRARY_END
MY_COMPANY_END

यदि आप सभी नेमस्पेस घोषणाओं को एक ही लाइन पर रखना चाहते हैं, तो आप ऐसा कर सकते हैं कि थोड़ा (बहुत बदसूरत) प्रीप्रोसेसर जादू के साथ:

// helper macros for variadic macro overloading
#define VA_HELPER_EXPAND(_X)                    _X  // workaround for Visual Studio
#define VA_COUNT_HELPER(_1, _2, _3, _4, _5, _6, _Count, ...) _Count
#define VA_COUNT(...)                           VA_HELPER_EXPAND(VA_COUNT_HELPER(__VA_ARGS__, 6, 5, 4, 3, 2, 1))
#define VA_SELECT_CAT(_Name, _Count, ...)       VA_HELPER_EXPAND(_Name##_Count(__VA_ARGS__))
#define VA_SELECT_HELPER(_Name, _Count, ...)    VA_SELECT_CAT(_Name, _Count, __VA_ARGS__)
#define VA_SELECT(_Name, ...)                   VA_SELECT_HELPER(_Name, VA_COUNT(__VA_ARGS__), __VA_ARGS__)

// overloads for NAMESPACE_BEGIN
#define NAMESPACE_BEGIN_HELPER1(_Ns1)             namespace _Ns1 {
#define NAMESPACE_BEGIN_HELPER2(_Ns1, _Ns2)       namespace _Ns1 { NAMESPACE_BEGIN_HELPER1(_Ns2)
#define NAMESPACE_BEGIN_HELPER3(_Ns1, _Ns2, _Ns3) namespace _Ns1 { NAMESPACE_BEGIN_HELPER2(_Ns2, _Ns3)

// overloads for NAMESPACE_END
#define NAMESPACE_END_HELPER1(_Ns1)               }
#define NAMESPACE_END_HELPER2(_Ns1, _Ns2)         } NAMESPACE_END_HELPER1(_Ns2)
#define NAMESPACE_END_HELPER3(_Ns1, _Ns2, _Ns3)   } NAMESPACE_END_HELPER2(_Ns2, _Ns3)

// final macros
#define NAMESPACE_BEGIN(_Namespace, ...)    VA_SELECT(NAMESPACE_BEGIN_HELPER, _Namespace, __VA_ARGS__)
#define NAMESPACE_END(_Namespace, ...)      VA_SELECT(NAMESPACE_END_HELPER,   _Namespace, __VA_ARGS__)

अब आप यह कर सकते हैं:

NAMESPACE_BEGIN(Foo, Bar, Baz)

class X { };

NAMESPACE_END(Baz, Bar, Foo) // order doesn't matter, NAMESPACE_END(a, b, c) would work equally well

Foo::Bar::Baz::X x;

तीन स्तरों से अधिक गहरे घोंसले के शिकार के लिए आपको वांछित गणना तक सहायक मैक्रोज़ को जोड़ना होगा।


जितना मुझे नापसंद है #defineमैं उस प्रीप्रोसेसर जादू से काफी प्रभावित हूँ ... केवल अगर मुझे गहरी घोंसले के शिकार के लिए अतिरिक्त सहायक मैक्रोज़ नहीं जोड़ना है ... तो, मैं इसे वैसे भी इस्तेमाल नहीं करने जा रहा हूँ। ।
गलादिन

12

C ++ नेमस्पेस का उपयोग ग्रुप इंटरफेस के लिए किया जाता है, घटकों को विभाजित करने या राजनीतिक विभाजन को व्यक्त करने के लिए नहीं।

जावा के समान नामस्थानों के उपयोग को रोकने के लिए मानक अपने रास्ते से हट जाता है। उदाहरण के लिए, नेमस्पेस अलापेस आसानी से गहरी-नेस्टेड या लंबे नामस्थान नामों का उपयोग करने का एक तरीका प्रदान करते हैं।

namespace a {
namespace b {
namespace c {}
}
}

namespace nsc = a::b::c;

लेकिन namespace nsc {}तब एक त्रुटि होगी, क्योंकि एक नामस्थान को केवल उसके मूल-नाम-नाम का उपयोग करके परिभाषित किया जा सकता है । अनिवार्य रूप से मानक ऐसी लाइब्रेरी के उपयोगकर्ता के लिए चीजों को आसान बनाता है लेकिन कार्यान्वयनकर्ता के लिए कठिन है । यह लोगों को ऐसी बातें लिखने से हतोत्साहित करता है, लेकिन अगर वे ऐसा करते हैं, तो उन प्रभावों को कम कर देता है।

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

अंडरस्कोर वर्णों और पहचानकर्ता उपसर्गों का उपयोग करने पर विचार करें जहां ::ऑपरेटर की आवश्यकता नहीं है।


17
ठीक है, तो विंडोज के बारे में क्या :: UI :: Xaml और विंडोज :: UI :: Xaml :: नियंत्रण :: विजेता के विकास में नाम स्थान? मुझे लगता है कि Microsoft नामस्थानों का उपयोग समझ में आता है और यह वास्तव में सिर्फ 2 स्तरों से अधिक गहरा है।
Beachwalker

2
2 से कम स्तरों का उपयोग करना लाल झंडा है और 3 या 4 का उपयोग करना पूरी तरह से ठीक है। एक फ्लैट नेमस्पेस पदानुक्रम को प्राप्त करने की कोशिश करना, जब यह समझ में नहीं आता है कि नाम स्थान के बहुत उद्देश्य को पराजित करता है - संघर्ष से बचना। मैं इस बात से सहमत हूं कि आपके पास एक इंटरफ़ेस के लिए एक स्तर होना चाहिए और उप-इंटरफ़ेस और आंतरिक के लिए दूसरा एक होना चाहिए। लेकिन इसके आसपास आपको कंपनी नेमस्पेस (छोटी से मध्यम कंपनियों के लिए) या कंपनी और डिवीजन के लिए दो (बड़ी कंपनियों के लिए) कम से कम एक स्तर की आवश्यकता होती है। अन्यथा आपका इंटरफ़ेस नेमस्पेस अन्य इंटरफेस के साथ एक ही नाम के साथ कहीं और विकसित होगा
कैसरलुडी

@Kaiserludi company::divisionओवर का तकनीकी लाभ क्या है company_division?
पोटाटोस्वाटर

@Potatoswatter इनसाइड कंपनी :: एक औरDivsion आप केवल छोटे 'डिवीजन' का उपयोग कर सकते हैं। कंपनी को संदर्भित करने के लिए :: हेडर के भीतर भी विभाजन जहां आपको 'नेमस्पेस का उपयोग' करके उच्च स्तर के नामस्थानों को प्रदूषित करने से बचना चाहिए। कंपनी के नामस्थान के बाहर आप अभी भी 'नेमस्पेस कंपनी का उपयोग कर सकते हैं?' जब डिवीजन के नाम आपके दायरे में किसी अन्य नामस्थान से नहीं टकराते हैं, लेकिन जब कुछ डिवीजन नेमस्पेस के अंदर इंटरफेस नाम टकराते हैं, तो आप 'नेमस्पेस company_division' का उपयोग नहीं कर सकते। '
कैसरलुडी

3
@Potatoswatter बिंदु यह है कि आप इसे व्यावहारिक रूप से मुफ्त में प्राप्त करते हैं (कंपनी :: डिवीजन company_division से अधिक लंबा नहीं है) और इसका उपयोग करने के लिए पहले एक अतिरिक्त नाम स्थान उपनाम को परिभाषित नहीं करना होगा।
कैसरलुडी

6

नहीं, और कृपया ऐसा न करें।

नामस्थानों का उद्देश्य मुख्य रूप से वैश्विक नामस्थान में संघर्षों का समाधान है।

एक माध्यमिक उद्देश्य प्रतीकों का स्थानीय संक्षिप्त नाम है; उदाहरण के लिए एक जटिल UpdateUIविधि using namespace WndUIछोटे प्रतीकों का उपयोग करने के लिए उपयोग कर सकती है ।

मैं 1.3MLoc प्रोजेक्ट पर हूं, और हमारे पास केवल नाम स्थान हैं:

  • आयातित बाहरी COM लाइब्रेरी (मुख्य रूप से #importऔर बीच के हेडर को अलग करने के लिए #include windows.h)
  • कुछ पहलुओं के लिए "सार्वजनिक एपीआई" नामस्थान का एक स्तर (यूआई, डीबी पहुंच आदि)
  • "कार्यान्वयन विस्तार" नामस्थान जो सार्वजनिक एपीआई (एनसीपी में अनाम नामस्थान, या ModuleDetailHereBeTygersहेडर-ही लिबास में नामस्थान) का हिस्सा नहीं हैं
  • enums मेरे अनुभव में सबसे बड़ी समस्या है। वे पागलों की तरह प्रदूषित करते हैं।
  • मुझे अभी भी लगता है कि यह पूरी तरह से कई नामस्थान है

इस परियोजना में, वर्ग के नाम आदि एक दो या तीन-अक्षर "क्षेत्र" कोड (जैसे के CDBNodeबजाय DB::CNode) का उपयोग करते हैं। यदि आप बाद वाले को पसंद करते हैं, तो "सार्वजनिक" नामस्थान के दूसरे स्तर के लिए जगह है, लेकिन अब और नहीं।

वर्ग-विशिष्ट एनम आदि उन वर्गों के सदस्य हो सकते हैं (हालांकि मैं मानता हूं कि यह हमेशा अच्छा नहीं होता है, और कभी-कभी यह कहना मुश्किल होता है कि आपको क्या करना चाहिए)

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


[संपादित करें] स्टेगी के अनुवर्ती प्रश्न के अनुसार:

ठीक है, तो विंडोज के बारे में क्या :: UI :: Xaml और विंडोज :: UI :: Xaml :: नियंत्रण :: विजेता के विकास में नाम स्थान? मुझे लगता है कि Microsoft नामस्थानों का उपयोग समझ में आता है और यह वास्तव में सिर्फ 2 स्तरों से अधिक गहरा है

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

अब, Microsoft मामला यकीनन अलग है। संभवतः एक बहुत बड़ी टीम है, और सभी कोड पुस्तकालय है।

मुझे लगता है कि Microsoft .NET लाइब्रेरी की सफलता की नकल कर रहा है, जहां नामस्थान व्यापक पुस्तकालय की खोज में योगदान करते हैं । (.NET में लगभग 18000 प्रकार हैं।)

मैं आगे यह मानूंगा कि एक नामस्थान में प्रतीकों का एक इष्टतम (परिमाण का क्रम) है। कहते हैं, 1 मतलब नहीं है, 100 सही लगता है, 10000 स्पष्ट रूप से बहुत है।


TL; DR: यह एक ट्रेडऑफ़ है, और हमारे पास हार्ड नंबर नहीं हैं। सुरक्षित खेलें, किसी भी दिशा में अति न करें। "ऐसा मत करो" केवल "आप के साथ समस्या है कि से आता है, मैं उस के साथ समस्या है, और मुझे कोई कारण नहीं है कि आपको इसकी आवश्यकता क्यों है।"


8
ठीक है, तो विंडोज के बारे में क्या :: UI :: Xaml और विंडोज :: UI :: Xaml :: नियंत्रण :: विजेता के विकास में नाम स्थान? मुझे लगता है कि Microsoft नामस्थानों का उपयोग समझ में आता है और यह वास्तव में सिर्फ 2 स्तरों से अधिक गहरा है।
बीचवॉकर

2
अगर मुझे वैश्विक-पहुंच स्थिरांक की आवश्यकता है, तो मैं उन्हें नाम के साथ एक नामस्थान में रखना पसंद करता हूं Constants, फिर स्थिरांक को वर्गीकृत करने के लिए उपयुक्त नामों के साथ नेस्टेड नामस्थान बनाएं; यदि आवश्यक हो, तो मैं नाम टकराव को रोकने के लिए आगे नामस्थान का उपयोग करता हूं। यह Constantsनाम स्थान प्रोग्राम के सिस्टम कोड के लिए एक कैच-ऑल नेमस्पेस में निहित है, जैसे कि एक नाम SysData। यह एक पूरी तरह से योग्य नाम तीन या चार नामस्थान युक्त (जैसे पैदा करता है SysData::Constants::ErrorMessages, SysData::Constants::Ailments::Bitflagsया SysData::Defaults::Engine::TextSystem)।
जस्टिन टाइम -

1
जब वास्तविक कोड में स्थिरांक की आवश्यकता होती है, तो किसी भी फ़ंक्शन की आवश्यकता होती है जो उन्हें usingउपयुक्त नामों में लाने के लिए एक निर्देश का उपयोग करता है , परस्पर विरोधी नामों की संभावना को कम करता है। मुझे लगता है कि यह पठनीयता में सुधार करता है, और किसी भी कोड ब्लॉक की निर्भरता के दस्तावेज़ में मदद करता है। इसके अलावा स्थिरांक से, मैं कोशिश करते हैं और (जैसे दो नामस्थान के लिए इसे रखने यदि संभव हो तो SysData::Exceptionsऔर SysData::Classes)।
जस्टिन टाइम -

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

2
-1 के लिए "कृपया ऐसा न करें" बिना उद्देश्य के कारण (बाद में स्पष्टीकरण के बावजूद)। भाषा नेस्टेड नेमस्पेस का समर्थन करती है और एक परियोजना के लिए उनके उपयोग के अच्छे कारण हो सकते हैं। इस तरह के संभावित कारणों और ऐसा करने के किसी भी ठोस, वस्तुनिष्ठ नुकसान की चर्चा मेरे पतन को उलट देगी।
टाइपिया

4

यहाँ Lzz (Lazy C ++) डॉक्स का एक उद्धरण :

Lzz निम्नलिखित C ++ निर्माण को पहचानता है:

नाम स्थान परिभाषा

अनाम फ़ाइल नाम और सभी संलग्न घोषणाएँ स्रोत फ़ाइल में आउटपुट हैं। यह नियम अन्य सभी को पछाड़ देता है।

एक नामित नाम स्थान का नाम योग्य हो सकता है।

   namespace A::B { typedef int I; }

के बराबर है:

   namespace A { namespace B { typedef int I; } }

बेशक ऐसे स्रोतों पर निर्भर होने वाले स्रोतों की गुणवत्ता बहस योग्य है ... मैं कहूंगा कि यह अधिक जिज्ञासा है, यह दिखाते हुए कि सी ++ द्वारा प्रेरित वाक्यविन्यास रोग कई रूप ले सकता है (मेरे पास, मेरा भी ...)


2

दोनों मानक (C ++ 2003 और C ++ 11) बहुत स्पष्ट हैं कि नाम स्थान का नाम एक पहचानकर्ता है। इसका मतलब है कि स्पष्ट नेस्टेड हेडर की आवश्यकता है।

मेरी धारणा है कि नाम के एक साधारण नाम के अलावा योग्य पहचानकर्ता रखने की अनुमति देना कोई बड़ी बात नहीं है, लेकिन किसी कारण से यह अनुमति नहीं है।


1

आप इस सिंटैक्स का उपयोग कर सकते हैं:

namespace MyCompany {
  namespace MyModule {
    namespace MyModulePart //e.g. Input {
      namespace MySubModulePart {
        namespace ... {
          class MyClass;
        }
      }
    }
  }
}

// Here is where the magic happens
class MyCompany::MyModule::MyModulePart::MySubModulePart::MyYouGetTheIdeaModule::MyClass {
    ...
};

ध्यान दें कि यह वाक्य रचना C ++ 98 में भी मान्य है और यह लगभग उसी तरह है जो अब C नेस्टेड 17 में नेस्टेड नेमस्पेस परिभाषाओं के साथ उपलब्ध है ।

खुश अनावश्यक!

सूत्रों का कहना है:


यह सवाल में उल्लिखित sytax है जहां इसके बजाय एक बेहतर समाधान खोजा जाता है। अब, C ++ 17 के साथ एक मान्य विकल्प उपलब्ध है, जैसा कि स्वीकृत उत्तर द्वारा बताया गया है। क्षमा करें, सवाल और जवाब नहीं पढ़ने के लिए नीचा दिखाना।
Beachwalker

@Beachwalker चलो सिंटैक्स पर पकड़ नहीं बनाते हैं। ऊपर दिए गए नाम स्थान की घोषणा स्वीकार्य उत्तर में भी हो सकती है। इस उत्तर को मुख्य बिंदु जो मैं उजागर करना चाहता था वह यह है कि ओपी ने कहा कि वह चूक गया था, और मैंने उस नेमस्पेस मेस के नीचे क्या किया। जहाँ तक मुझे लगता है कि हर कोई नाम स्थान के भीतर सब कुछ घोषित करने पर ध्यान केंद्रित किया गया लगता है, जबकि मेरा जवाब आपको नेस्टेड मेस से बाहर ले जाता है और मुझे यकीन है कि ओपी ने इस वाक्य रचना की सराहना की होगी, किसी ने 4 साल पहले इसका उल्लेख किया था जब यह सवाल पहले पूछा गया था।
smac89

1

यह पेपर विषय को अच्छी तरह से कवर करता है: नेमस्पेस पेपर

जो मूल रूप से इसे उबालता है। जितने लंबे समय तक आपके नाम स्थान पर रहने की संभावना है कि लोग using namespaceनिर्देश का उपयोग करने जा रहे हैं ।

तो निम्न कोड को देखते हुए आप एक उदाहरण देख सकते हैं जहाँ यह आपको चोट पहुँचाएगा:

namespace abc { namespace testing {
    class myClass {};
}}

namespace def { namespace testing {
    class defClass { };
}}

using namespace abc;
//using namespace def;

int main(int, char**) {
    testing::myClass classInit{};
}

यह कोड ठीक संकलित करेगा, हालांकि, यदि आप लाइन को अनफॉलो करते हैं //using namespace def;तो "टेस्टिंग" नामस्थान अस्पष्ट हो जाएगा और आपके पास नामकरण टकराव होगा। इसका मतलब यह है कि आपका कोड आधार एक तीसरी पार्टी लाइब्रेरी को शामिल करके स्थिर से अस्थिर तक जा सकता है।

सी # में, आप का उपयोग करने के लिए गए थे, भले ही using abc;और using def;संकलक कि पहचान करने में सक्षम है testing::myClassया बस myClassकेवल में है abc::testingनाम स्थान है, लेकिन सी ++ इस पहचान नहीं होगा और यह एक टक्कर के रूप में पाया जाता है।


0

हां, आपको इसे पसंद करना होगा

namespace A{ 
namespace B{
namespace C{} 
} 
}

हालाँकि, आप नामस्थानों का उपयोग इस तरह से करने का प्रयास कर रहे हैं कि उनका उपयोग नहीं किया जाना चाहिए। इस प्रश्न की जाँच करें , शायद आपको यह उपयोगी लगे।


-1

[EDIT:]
चूंकि c ++ 17 नेस्टेड नेमस्पेस एक मानक भाषा सुविधा ( https://en.wikipedia.org/wiki/C%2B%2B17 ) के रूप में समर्थित हैं । अब तक, यह सुविधा g ++ 8 में समर्थित नहीं है, लेकिन इसे clang ++ 6.0 संकलक में पाया जा सकता है।


[निष्कर्ष:] अपने डिफ़ॉल्ट संकलन कमांड के रूप में
उपयोग करें clang++6.0 -std=c++17। तब सब कुछ ठीक काम करना चाहिए - और आप namespace OuterNS::InnerNS1::InnerNS2 { ... }अपनी फाइलों में संकलित कर पाएंगे ।


[मूल उत्तर:]
क्योंकि यह प्रश्न थोड़ा पुराना है, इसलिए मैं मान लूंगा कि आप आगे बढ़ चुके हैं। लेकिन दूसरों के लिए, जो अभी भी एक उत्तर की तलाश में हैं, मैं निम्नलिखित विचार के साथ आया:

Emacs बफ़र मुख्य फ़ाइल, नाम स्थान फ़ाइलें, संकलन आदेश / परिणाम और कमांड-लाइन निष्पादन दिखाते हैं।

(शायद मैं यहाँ Emacs के लिए एक विज्ञापन कर सकता हूँ :)?) एक छवि पोस्ट करना बहुत आसान है, और अधिक पठनीय है, बस पोस्ट कोड की तुलना में। मैं सभी कोने के मामलों का पूर्ण रूप से पहचाना गया एवरेज प्रदान करने का इरादा नहीं रखता, बस मुझे कुछ प्रेरणा देने का मतलब था। (मैं पूरी तरह से C # का समर्थन करता हूं और महसूस करता हूं कि कई मामलों में C ++ को कुछ OOP विशेषताओं को अपनाना चाहिए, क्योंकि C # मुख्य रूप से इसके उपयोग में आसानी के कारण लोकप्रिय है)।


अपडेट: चूंकि C ++ 17 ने नेमस्पेसिंग ( nuonsoft.com/blog/2017/08/01/c17-nested-namespaces ) को नेस्टेड किया है , ऐसा लगेगा कि मेरा जवाब अब प्रासंगिक नहीं है, जब तक कि आप C ++ के पुराने संस्करणों का उपयोग नहीं कर रहे हैं। ।
き ん ワ

1
मुझे जितना भी Emacs से प्यार है, एक छवि पोस्ट करना आदर्श नहीं है। यह पाठ खोज / अनुक्रमण को हटाता है, और दृष्टिबाधित आगंतुकों के लिए उपयोग करने के लिए आपके उत्तर को भी कठिन बनाता है।
हेनरिक
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.