2010-12-05 17 views
17

विश्वसनीय तर्क againstusing namespace std हैं, तो यह भाषा में बिल्कुल क्यों पेश किया गया था? using namespace नामस्थानों के उद्देश्य को हराने नहीं है? मैं कभी भी using namespace क्यों लिखना चाहूंगा? क्या कोई समस्या है, मुझे पता नहीं है कि using namespace द्वारा सुंदरता से हल किया गया है, शायद using std::swap मुहावरे या कुछ ऐसा है?का उद्देश्य क्या है: "नेमस्पेस का उपयोग करना"?

+11

कम टाइपिंग एक बहुत मोहक तर्क 'का उपयोग कर' चारों ओर नाम स्थान के खिलाफ काम कर रहा है या उपयोग करने की अवधारणा है ... – delnan

+0

, लेकिन यह है वहां आपको इसकी आवश्यकता होती है। – kenny

+3

हर्ब सटर के ["नामांकन के लिए माइग्रेटिंग" भी देखें।] (Http://www.gotw.ca/publications/migrating_to_namespaces.htm) –

उत्तर

21

एक बात के लिए, इस तरह से एक नाम स्थान (उदाहरण, using namespace std::rel_ops; या using namespace boost::assign;)

संक्षिप्तता भी एक मजबूत तर्क है में ऑपरेटर भार के उपयोग करने के लिए है। क्या आप वाकई _1 के बजाय std::placeholders::_1 टाइपिंग और पढ़ने का आनंद लेंगे? साथ ही, जब आप कार्यात्मक शैली में कोड लिखते हैं, तो आप std और boost नामस्थान में ऑब्जेक्ट्स का असंख्य उपयोग करेंगे।

एक अन्य महत्वपूर्ण उपयोग (हालांकि सामान्य रूप से एक पूरे नामस्थान आयात नहीं करता है) में सक्षम बनाना है तर्क पर निर्भर लुक-अप:

template <class T> 
void smart_swap(T& a, T& b) 
{ 
    using std::swap; 
    swap(a, b); 
} 

स्वैप टी के रूप में ही नाम स्थान में टी के कुछ प्रकार के लिए ओवरलोड हो गया है, तो , यह उस अधिभार का उपयोग करेगा। यदि आपने स्पष्ट रूप से std::swap कहा है, तो उस अधिभार पर विचार नहीं किया जाएगा। अन्य प्रकार के लिए यह std::swap पर वापस आता है।

बीटीडब्लू, एक घोषणा घोषणा/निर्देश नामस्थानों के उद्देश्य को हराने नहीं देता है, क्योंकि आप हमेशा अस्पष्टता के मामले में नाम को पूरी तरह अर्हता प्राप्त कर सकते हैं।

+0

+ 1, यह एक बहुत ही व्यवस्थित कलाकृति है :) –

+2

व्यक्तिगत रूप से मैं " का उपयोग करके" ठीक हूं, "नामस्थान का उपयोग करके" मुझे समस्या है (rel_ops जैसे कुछ अपवादों के साथ)। –

2

ज्यादातर बार यह कोड लिखने के लिए एक शॉर्टकट है। आप अपने संलग्न संदर्भ में नाम आयात कर सकते हैं। मैं आमतौर पर इसे .cpp फ़ाइलों तक सीमित करता हूं, क्योंकि जब आप .h फ़ाइल में एक निर्देश का उपयोग शामिल करते हैं, तो यह उन सभी फ़ाइलों को प्रदूषित करता है जिनमें इसे शामिल किया गया है। एक और अच्छा अभ्यास using namespace को सबसे अधिक संलग्न वातावरण में प्रतिबंधित करना है, उदाहरण के लिए, एक विधि निकाय घोषणा के अंदर। मैं एक सुविधा के रूप में देखते हैं, कोई और अधिक, और इस तरह के रूप में अलियासिंग नाम स्थान के लिए, समान:

namespace po = boost::program_options; 

और फिर आप

po::variables_map ... 
0

लोग विशेष रूप से using namespace BigCorp को using namespace std; लेकिन नहीं पर आपत्ति लिख सकते हैं; या std::cout का संदर्भ देने के लिए (जो नामस्थान का उपयोग कर रहा है, बस using नहीं, अगर आपको पता है कि मेरा क्या मतलब है।) इसके अलावा, using namespace std पर अधिकांश आपत्तियां हेडर फ़ाइल में हैं। एक स्रोत फ़ाइल में, जहां प्रभाव तुरंत देखा जा सकता है, यह कम हानिकारक है।

नेमस्पेस एक अविश्वसनीय रूप से उपयोगी अवधारणा है जो मुझे तिथि नामक कक्षा रखने की अनुमति देती है, भले ही मैं जिस लाइब्रेरी का उपयोग कर रहा हूं उसे डेट कहा जाता है। भाषा में जोड़े जाने से पहले, हमें GCDate और GCString (मेरी कंपनी, ग्रेगरी परामर्श, std::string की भविष्यवाणी) जैसी चीजें थीं। नामस्थानों का उपयोग करना (using कीवर्ड के साथ या बिना) हम सभी क्लीनर, नीदर कोड लिखने देते हैं। लेकिन जब आपको हर बार Gregcons::string कहना है, तो आप क्लीनर, निएटर भाग खो देते हैं। [अस्वीकरण: मैं वास्तव में अपनी खुद की स्ट्रिंग क्लास का उपयोग नहीं करता - कुछ उचित नाम संघर्ष की कल्पना करें।] यह using कथन की अपील है। इसे हेडर से बाहर रखें, इसे std पर लागू न करें, और आपको आमतौर पर परेशानी से बाहर रहना चाहिए।

+0

मैं कहूंगा, 'नेमस्पेस foo' का उपयोग न करें, लेकिन' foo :: जो भी हो; जो मानक और अन्य नामों दोनों के लिए लागू होता है। उदाहरण के लिए यदि शीर्षलेख में नहीं किया गया है तो 'std :: cout' का उपयोग करके कुछ भी गलत नहीं है। – celtschk

0

मुझे गहरा घोंसला वाले नामस्थानों के साथ पुस्तकालयों के साथ काम करते समय यह उपयोगी लगता है। बूस्ट लाइब्रेरी एक ऐसा उदाहरण है। इमेजिंग टाइपिंग boost::numeric::ublas::matrix<double> m सभी जगह ...

एक हेडर फ़ाइल में using namespace से बचने की बात है क्योंकि इसमें हेडर शामिल किसी भी प्रोग्राम को रॉयली खराब करने की संभावना है। हमेशा .cpp/.cxx फ़ाइलों में using namespace कथन रखें, ताकि यह फ़ाइल स्कोप तक सीमित हो।

+2

लेकिन नामस्थान उपनाम इसे भी हल कर सकता है। या आप केवल चुनिंदा रूप से 'मैट्रिक्स' आयात कर सकते हैं। – jalf

+2

या आप टाइपिफ़ का उपयोग कर सकते हैं, उदा। 'typedef boost :: numeric :: ublas :: matrix DoubleMatrix' और अपने शेष कोड में 'DoubleMatrix' का उपयोग करें। यह सी ++ की सुंदरता/अभिशाप है: एक ही समस्या को हल करने के लिए कई दृष्टिकोण हैं। – CadentOrange

-1

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

अधिक यहाँ जानकारी: http://www.cplusplus.com/doc/tutorial/namespaces/

1

मुख्य कारण using namespace पेश किया गया था पीछे की ओर था संगतता: यदि आप पूर्व नाम स्थान कोड के बहुत सारे है, तो मानक पुस्तकालय कार्यों और कक्षाओं के बहुत से (पूर्व-मानक संस्करण) का उपयोग करके, आप इसे बनाने का एक आसान तरीका चाहते हैं मानक अनुरूप कंपाइलर के साथ कोड काम।

Btw, के लिए सी ++ 98 कम से कम तर्क निर्भर देखने नियमों का मतलब है कि using namespace std::rel_opsनहीं क्या आप टेम्पलेट्स में चाहते हैं (मैं अगर यह मानक के बाद के संस्करण में बदल पता नहीं है) नहीं होगा।

उदाहरण:

template<typename T> bool bar(T t) 
{ 
    return t > T(); 
} 

namespace foo 
{ 
    class X {}; 
    bool operator<(X, X); 
} 

using namespace std::rel_ops; 

int main() 
{ 
    X x; 
    bar(x); // won't work: X does not have operator> 
} 

ध्यान दें कि डाल namespace foo में using namespace या तो मदद नहीं करेगा।

हालांकि, सही जगह मदद में घोषणाओं का उपयोग कर:

template<typename T> bool bar(T t) 
{ 
    return t > T(); 
} 

namespace foo 
{ 
    class X {}; 
    bool operator<(X, X); 
    using std::rel_ops::operator>; 
} 

int main() 
{ 
    X x; 
    bar(x); // now works: operator> found per ADL via the using declaration in `namespace foo` 
}