2009-11-02 11 views
23

ऐसा लगता है कि अनचाहे नामस्थानों का उपयोग करना केवल बाद में परेशानी के लिए पूछ रहा है जब कोई नया नामस्थान रखता है जो रूट स्तर नामस्थान के समान नाम होता है और रहस्यमय रूप से पूरे कार्यक्रमों के अर्थ को बदल देता है। तो, ::std:: के बजाय लोग हमेशा std:: क्यों कहते हैं। क्या वे वास्तव में कहने का मतलब रखते हैं "मैं जो भी std उपयोग करना चाहता हूं, वह रूट नहीं है।"सभी लोग अनचाहे नेमस्पेस घोषणाओं का उपयोग क्यों करते हैं (यानी std :: not :: std: :)?

फ्रेड/Foo.h में:

#include <string> 

namespace fred { 

class Foo { 
public: 
    void aPublicMember(const std::string &s); 
}; 

} // end namespace fred 

फ्रेड/Bar.h में:

namespace fred { 
namespace std { // A standard fred component 

class string { // Something rather unlike the ::std::string 
    // ... 
}; 

} // namespace std 

class Bar { 
public: 
    void aPublicMember(std::string &s); 
}; 

} // namespace fred 

oops.cpp में

यहाँ मैं क्या मतलब का एक उदाहरण है:

#include <string> 
#include "fred/Bar.h" 
#include "fred/Foo.h" // Oops, the meaning of Foo is now different. 

क्या लोग चाहते हैं, या मैं हूं मुझे कुछ याद आ रहा है?

और शायद आप कहें कि आपको कभी नामस्थान std नाम नहीं देना चाहिए। और यह सब ठीक है और अच्छा है, लेकिन फिर कुछ अन्य रूट लेवल नेमस्पेस के बारे में क्या? क्या किसी भी रूट स्तर का नामस्थान किसी भी व्यक्ति को कभी भी परिभाषित करता है, हमेशा उप-नामस्थान नाम के लिए ऑफ-सीमा हो?

स्पष्टीकरण के लिए, मुझे कोई जवाब नहीं मिलेगा जो मुझे बताता है कि std विशेष है क्योंकि मैंने इसे अभी एक उदाहरण के रूप में उपयोग किया है। मैं एक सामान्य मुद्दे के बारे में बात कर रहा हूं, और मैं इसका वर्णन करने के लिए std का उपयोग कर रहा हूं, हालांकि मैं मानता हूं कि यह एक चौंकाने वाली प्रोप है।

उत्तर

14

अनचाहे नामस्थानों का व्यावहारिक कारण यह है कि नामों का एक स्तर आमतौर पर पर्याप्त होता है। जब ऐसा नहीं होता है, तो आमतौर पर कार्यान्वयन के विवरण के लिए दूसरे स्तर का उपयोग किया जा रहा है। और अंत में, कई स्तरों का उपयोग करते समय भी, वे आमतौर पर रूट स्तर से निश्चित रूप से निर्दिष्ट होते हैं। अर्थात। नामस्थान ns1 के अंदर भी, आप आमतौर पर ns1::ns2::foons2::foo या ::ns1::ns2::foo के बजाय देखेंगे।

तो, इन तीन कारणों से ::ns1 फॉर्म सामान्य मामलों में अनावश्यक है। एकमात्र मामला जहां मैं विचार करता हूं कि यह बूस्ट को सबमिशन में होगा, क्योंकि बूस्ट लेखक के रूप में मुझे नहीं पता होगा कि मेरे सॉफ़्टवेयर का उपयोग कब किया जाएगा।

+0

मैं इसे स्वीकार करने जा रहा हूं क्योंकि यह वास्तविक उत्तर के सबसे नज़दीकी है। मुझे लगता है कि दूसरे को सिर्फ उच्च वोट दिया गया था क्योंकि यह मजेदार था। :-) मुझे संदेह है कि मुझे एक अलग उदाहरण चुना जाना चाहिए था, या मैंने इस तरह से सवाल नहीं पूछा था। – Omnifarious

2

std के मामले में मैं उसी नाम, समान वर्गों के साथ किसी भी अन्य नामस्थान को नहीं मानूंगा लेकिन अलग-अलग अर्थ।

अन्य मामलों में, अग्रणी :: सिर्फ बदसूरत दिखता है, और पढ़ने कोड को और अधिक कठिन बनाता है (मेरी राय में)। सब कुछ के सामने :: डालने के लिए नेमस्पेस संघर्ष बहुत दुर्लभ हैं।

3

यह इतना कृत्रिम है:

namespace fred { 
namespace std { // A standard fred component 

class string { // Something rather unlike the ::std::string 
    // ... 
}; 

} // namespace std 
} // namespace fred 

यह फ्रेड व्याख्या करने में सक्षम क्यों वह कि करने के लिए पूरी टीम किया नहीं होगा।

अपने प्रश्न का उत्तर देने के लिए: लोग पहले "::" छोड़ देते हैं क्योंकि यह एक आदत है, जो समय बचाती है और क्योंकि यह अपेक्षा करना आसान है कि जब नामस्थान कहीं भी उपयोग किया जाता है, तो ऐसा नाम पूर्ण, सापेक्ष नहीं है।

+3

फ्रेड को LART के साथ हिट करने की आवश्यकता है। – user7116

7

क्यों लोगों को हमेशा std ::

नहीं हमेशा कहते है। मैं string और using ::std::string का उपयोग करता हूं। तो fred::std::string होने पर कुछ भी बुरा नहीं है, क्योंकि मैं अभी भी std::string का उपयोग करता हूं। छोटी सीपीपी फाइलों में यह using namespace ::std भी हो सकता है।नमूना:

#include <iostream> 
using ::std::string; 
//using namespace ::std; // good for small cpp-files 

int main() 
{ 
    string s = "sometext"; // no leading ::std 
} 

तुम सिर्फ एक नाम स्थान एसटीडी

हाँ नाम कभी नहीं करना चाहिए, तो आप कस्टम नाम स्थान के लिए एक नाम std नहीं देना चाहिए।

2

वैश्विक नामस्थान में बहुत से कोड लिखे गए हैं। अगर कोई वास्तव में :: std :: को फिर से परिभाषित करता है, तो इससे कोई फर्क नहीं पड़ता कि आप इस तरह के कोड में इसका संदर्भ कैसे देते हैं।

इसके अलावा, आपका परिदृश्य दोनों काम करने की संभावना नहीं है और काम करने में आसान है। सबसे पहले, एक 'std' था के बाद से सम्मेलन यह था कि आप उस नाम का उपयोग नहीं करते हैं। दूसरी बात यह है कि यदि आप एक पैकेज है कि 'एसटीडी' नाम स्थान में परिभाषित सामना करने के लिए थे, तो आप सिर्फ इस कार्य करें:

#include <package_name.hpp> 

namespace package_name { 
    using namespace std; 
} 

namespace my_app { 
    class my_class : public package_name::class_of_something {}; 
} 

या कुछ इसी तरह की। आपको स्पष्ट रूप से std के रूप में :: std का नाम देना पड़ सकता है। मेरा मुद्दा यह है: लोग हर समय अन-एंकर 'std ::' का उपयोग करने के बारे में जाते हैं क्योंकि यहां तक ​​कि सबसे बुरी स्थिति के परिणाम भी एक बड़ा सौदा नहीं है, और उस पर असंभव नहीं है।

2

ठीक है, आप कहते हैं कि std केवल एक उदाहरण है। लेकिन मेरे लिए ऐसा लगता है कि आपका प्रश्न केवल उस मामले पर लागू होता है जहां कोई std ओवरराइड करने के रूप में कुछ बुरा करता है। prepending :: परिणाम डिफ़ॉल्ट व्यवहार में

namespace logging 
{ 
    // Logs to local file 
} 

namespace server 
{ 
    namespace logging 
    { 
     // Logs to remote destination 
    } 
} 

namespace client 
{ 
    namespace logging 
    { 
     // Logs to local file and to screen 
    } 
} 

इस मामले में, नहीं:

मुझे एक और उदाहरण प्रदान करते हैं।

+0

यह एक उत्कृष्ट कारण है कि कुछ परिस्थितियों में रिश्तेदार नामस्थान का उपयोग क्यों किया जाना चाहिए, मैं निश्चित रूप से सहमत हूं। – Omnifarious

+0

लेकिन आपकी कक्षा में, क्या होता है जब कोई व्यक्ति अपने नामस्थान 'क्लाइंट' में नामस्थान 'सर्वर' बनाता है ताकि सर्वर से संबंधित चीजों को संदर्भित किया जा सके जो ग्राहक की परवाह है? – Omnifarious

+0

@ प्रायः मैं बस यह दिखाना चाहता था कि उत्तर इस प्रश्न के लिए आपके द्वारा दिए गए उदाहरण पर निर्भर करता है। वैसे भी: मैं कहूंगा कि यह अपने स्वयं के एसडीडी नेमस्पेस को बनाने के रूप में लगभग बुरा होगा। यदि "सर्वर" की बजाय कॉन्फ़िगरेशन आदि के लिए संचार या "सर्वर कॉन्फ़िगर" के बारे में कोई "सर्वरकॉम" का उपयोग कर सकता है। – foraidt

33

तो, क्यों लोग हमेशा कहते हैं std :: बजाय :: std ::

शायद क्योंकि वे वास्तव में कभी नहीं इसकी वजह से अस्पष्टता के साथ समस्या थी।

समान पंक्तियों के साथ: मुझे अपने पते में "पृथ्वी" कभी भी शामिल नहीं करना पड़ा, और मैं नहीं जा रहा हूं।

आपको कहीं रेखा खींचनी है, और यह एक उचित धारणा है कि अन्य लोग अपना स्वयं का नाम नहीं रखेंगे, या कम से कम एक लाइब्रेरी जो बहुत लोकप्रिय नहीं होगी। :)

+0

हास्य के लिए +1 [15 char filler] – foraidt

+2

* चकले * ठीक है, अगर मैं एंड्रोमेडा में रह रहा था और पृथ्वी पर किसी को संदर्भित करना चाहता था, तो शायद मैं 'स्थानीय समूह' पर बाहर निकल जाऊंगा, लेकिन इसमें 'मिल्की वे' , 'सोल सिस्टम', और 'अर्थ'। – Omnifarious

+2

लेकिन मानव जाति को इस चट्टान से तकनीकी रूप से विकसित करने की आवश्यकता है इससे पहले कि यह चिंता का विषय है – Hardryv

1

उसी तरह से _ के साथ उपसर्ग किए गए नाम आरक्षित हैं, std:: पर आरक्षित के रूप में अच्छी तरह से विचार करें।

+0

हालांकि पैडेंटिक होने के बावजूद, अंडरस्कोर द्वारा उपसर्ग किए गए सभी नाम आरक्षित हैं। – GManNickG

+0

हां, सब कुछ नहीं। क्या किसी को पूरी तरह से गर्व में रुचि होनी चाहिए, [इसे पढ़ें] (http://stackoverflow.com/questions/228783/what-are-the-rules-about-using-an-underscore-in-a-c-identifier) –

संबंधित मुद्दे