2013-02-07 42 views
11

लघु फॉर्म में वैश्विक नामस्थान को उपनाम कैसे करें: मैं C++ 11 में रूट (वैश्विक) नामस्थान के लिए उपनाम कैसे परिभाषित कर सकता हूं? ऐसा लगता है किसी ++ 11

namespace root_namespace = :: ;

जहां इसकी नग्न रूप में गुंजाइश संकल्प ऑपरेटर ऊपर ग्लोबल नेम स्पेस में से कुछ संभाल के लिए एक जगह धारक है लग सकता है। मैंने GCC Internals Manual में पढ़ा है कि

... [कंपाइलर] संपूर्ण मध्यवर्ती प्रतिनिधित्व की जड़ वैरिएबल global_namespace है। यह C12+ स्रोत कोड में :: के साथ निर्दिष्ट नामस्थान है ... वैश्विक नामस्थान का नाम :: है, भले ही सी ++ में वैश्विक नामस्थान का नाम बदल दिया गया हो।

पुनश्च संपादित: टू-डेट उत्तरदाताओं को, मैं एक painfuly लंबे प्रपत्र, निम्नलिखित लंबे प्रपत्र के बाद कुछ चिंताओं को दूर करने के बाद से यह कुछ चीजें स्पष्ट कर सकता है संलग्न। और अनुयायियों, अगर आप हमें नहीं बल्कि एक दूसरे से तुलना पर बात कर देखते हैं, में खुदाई


लौंग फॉर्म:। इसकी क्षमता उपयोग का एक उदाहरण इस प्रकार है। अगर असंतोषजनक है, तो हाँ, यह एक अकादमिक सवाल है; दर्दनाक रूप से लंबे फार्म देखें जो इस का पालन करता है।

कल्पना कीजिए कि आपका मालिक एक दिन में घुसता है और कहता है, "मैंने पोस्ट-पॉजिटिवज्म के बारे में एक पुस्तक पढ़ी है। namespace ObjectiveReality से छुटकारा पाएं।" नीचे दिए गए कोड में, 'सब' आपको करना है, मैंने /* -> */ जैसे /* <- */ जैसे चिह्नित लाइनों को छोड़ दिया है। आप कर सकते हैं वर्तमान में घोंसले के मध्यवर्ती स्तर के लिए; हालांकि, मुझे अनिश्चितता है कि वैश्विक गैर-वैश्विक नामस्थान के सरल elision की अनुमति देने के लिए वैश्विक स्कोप namespace current_authority को कैसे परिभाषित किया जाए।

#include <iostream> 
#include <iomanip> 


// ... 
using cat_is_alive = std::true_type ; // because I like cats 
using cat_is_alive = ::cat_is_alive ; // seems to work, see `g++ -v` below 
// ... 


// ASIDE: I originally had `namespace higher_authority = COMPILER ;` as a comment, but changed it for simpler chaining closure 

// The next two lines are the crux of my question... 

namespace higher_authority = global_namespace ; 
namespace current_authority = global_namespace ; // a.k.a. the naked :: 

// If the above two lines defined aliases for the (unnamed) global namespace, then the suggested elisions/replacements work... 

/* -> */ 
namespace ObjectiveReality { 
/* <- */ 
// Simplest fix: replace with `using ObjectiveReality = current_authority ;` 
// (Otherwise, a few other changes are necessary) 

    namespace higher_authority = current_authority ; 
    namespace current_authority = ObjectiveReality ; 

    using cat_is_alive = higher_authority::cat_is_alive ; 

    namespace EntangledObserver { 

     namespace higher_authority = current_authority ; 
     namespace current_authority = EntangledObserver ; 

     using cat_is_alive = higher_authority::cat_is_alive ; 
    } ; 
/* -> */ 
} ; 
/* <- */ 


int main(int argc, char** argv) { 

    std::cout 
     << "It is " 
     << ObjectiveReality::EntangledObserver::cat_is_alive::value 
     << " that the cat is alive." << std::endl ; 

    return 0 ; 
} 


// EOF 

मामले संकलक की जानकारी में की जरूरत है:

$ g++ -std=c++11 -v 

Using built-in specs. 
COLLECT_GCC=g++ 
COLLECT_LTO_WRAPPER=/usr/lib/gcc/i686-linux-gnu/4.7/lto-wrapper 
Target: i686-linux-gnu 
Configured with: ../src/configure -v --with-pkgversion='Ubuntu/Linaro 4.7.2-11precise2' 
--with-bugurl=file:///usr/share/doc/gcc-4.7/README.Bugs 
--enable-languages=c,c++,go,fortran,objc,obj-c++ --prefix=/usr --program-suffix=-4.7 
--enable-shared --enable-linker-build-id --with-system-zlib --libexecdir=/usr/lib 
--without-included-gettext --enable-threads=posix 
--with-gxx-include-dir=/usr/include/c++/4.7 --libdir=/usr/lib 
--enable-nls --with-sysroot=/ --enable-clocale=gnu --enable-libstdcxx-debug 
--enable-libstdcxx-time=yes --enable-gnu-unique-object --enable-plugin 
--enable-objc-gc --enable-targets=all --disable-werror --with-arch-32=i686 
--with-multilib-list=m32,m64 --with-tune=generic --enable-checking=release 
--build=i686-linux-gnu --host=i686-linux-gnu --target=i686-linux-gnu 
Thread model: posix 
gcc version 4.7.2 (Ubuntu/Linaro 4.7.2-11precise2) 

दर्दनाक लौंग फॉर्म: के बारे में "एक नेस्टेड नाम स्थान से शुरू करते हैं," कृपया ध्यान दें कि 'घर कुछ जवाब के लिए एक प्रतिक्रिया के रूप में! ' पहुंच योग्य नहीं है, और मेरे पास एक टीम में हैंड-पिकिंग नेमस्पेस की लक्जरी नहीं हो सकती है।

// 
// alice.cpp 
// 


#include <iostream> 
#include <type_traits> 


///// 
///// The Setup 
///// 

// 
// One-and-a-half macros 
// 

// BOO! Get rid of this case! 
#define ENABLE_SUBSPACE_1(namespace_name) \ 
    namespace namespace_name { \ 
    namespace last_namespace = ::namespace_name ; \ 
    namespace this_namespace = ::namespace_name ; 

// YEAH! Instead, define 'namespace this_namespace = :: ;' and then... 
#define ENABLE_SUBSPACE(namespace_name) \ 
    namespace namespace_name { \ 
    namespace last_namespace = this_namespace ; \ 
    namespace this_namespace = last_namespace::namespace_name ; 

// 
// Some characters 
// 

struct dorothy { 
    static constexpr auto obvious_statement = "There's no place like " ; 
} ; 

struct rabbit { 
    template< typename T > 
    static constexpr char const* says(T) { 
     return T::value ? "I'm late!" : "I'm late, but I ditched that addled girl." ; 
    } 
} ; 

struct alice { 

    using blue_pill = std::false_type ; 
    static constexpr auto where_am_i = "HOME!" ; 
} ; 


///// 
///// The Central Structure 
///// 

ENABLE_SUBSPACE_1(oxford_england) // { 

    using has_strangers_with_candy = std::true_type ; 

    struct alice { 
     using blue_pill = this_namespace::has_strangers_with_candy ; 
     static constexpr auto where_am_i = "Uncle Charles' picnic blanket." ; 
    } ; 

ENABLE_SUBSPACE(rabbit_hole) // { 
    struct rabbit { using is_late = typename alice::blue_pill ; } ; 
ENABLE_SUBSPACE(rabbit_hole) // { 
    struct rabbit { using is_late = typename alice::blue_pill ; } ; 
ENABLE_SUBSPACE(rabbit_hole) // { 
    struct rabbit { using is_late = typename alice::blue_pill ; } ; 
    using has_strangers_with_candy = std::false_type ; ///// Different... 
ENABLE_SUBSPACE(rabbit_hole) // { 
    struct rabbit { using is_late = typename alice::blue_pill ; } ; 
ENABLE_SUBSPACE(rabbit_hole) // { 
    struct rabbit { using is_late = typename alice::blue_pill ; } ; 
    struct alice { ///// Different... 
     using blue_pill = has_strangers_with_candy ; 
     static constexpr auto where_am_i = "needing a fix." ; 
    } ; 
ENABLE_SUBSPACE(rabbit_hole) // { 
    struct rabbit { using is_late = typename alice::blue_pill ; } ; 
    struct alice : last_namespace::alice { ///// Different... 
     static constexpr auto where_am_i = "an empty rabbit hole." ; 
    } ; 
} ; // END rabbit_hole 
} ; // END rabbit_hole 
} ; // END rabbit_hole 
} ; // END rabbit_hole 
} ; // END rabbit_hole 
} ; // END rabbit_hole 
} ; // END oxford_england 


///// 
///// Snarky Output 
///// 

int main(int argc, char** argv) { 

    std::cout << std::endl 
     << dorothy::obvious_statement 
     << alice::where_am_i 
     << std::endl ; // There's no place like HOME! 

    std::cout 
     << dorothy::obvious_statement 
     << oxford_england::rabbit_hole::rabbit_hole::rabbit_hole::rabbit_hole::rabbit_hole::alice::where_am_i 
     << std::endl ; // There's no place like needing a fix. 

    std::cout 
     << dorothy::obvious_statement 
     << oxford_england::rabbit_hole::rabbit_hole::rabbit_hole::rabbit_hole::rabbit_hole::rabbit_hole::alice::where_am_i 
     << std::endl ; // There's no place like an empty rabbit hole. 

    std::cout << std::endl 
     << rabbit::says(
      oxford_england:: 
       rabbit_hole:: 
        rabbit_hole:: 
         rabbit_hole:: 
          rabbit_hole:: 
           rabbit_hole::rabbit::is_late() 
     ) << std::endl ; // I'm late! 
    std::cout 
     << rabbit::says(
      oxford_england:: 
       rabbit_hole:: 
        rabbit_hole:: 
         rabbit_hole:: 
          rabbit_hole:: 
           rabbit_hole:: // NOTE : alice::blue_pill is false_type 
            rabbit_hole::rabbit::is_late() // ... not this time ; Alice is crashing. 
     ) << std::endl ; // I'm late, but I ditched that addled girl. 

    std::cout << std::endl 
     << dorothy::obvious_statement 
     << oxford_england:: 
       rabbit_hole:: // 1 
        rabbit_hole:: // 2 
         rabbit_hole:: // 3 
          rabbit_hole:: // 4 
           rabbit_hole:: // 5 
            rabbit_hole:: // rabbit_hole #6 
           last_namespace:: // rabbit_hole #5 
          last_namespace:: // rabbit_hole #4 
         last_namespace:: // rabbit_hole #3 
        last_namespace:: // rabbit_hole #2 
       last_namespace:: // rabbit_hole #1 
      last_namespace::alice::where_am_i // oxford_england 
     << std::endl ; // There's no place like Uncle Charles' picnic blanket. 
    std::cout 
     << dorothy::obvious_statement 
     << oxford_england:: 
       rabbit_hole:: 
        rabbit_hole:: 
         rabbit_hole:: 
          rabbit_hole:: 
           rabbit_hole:: 
            rabbit_hole:: 
           last_namespace:: 
          last_namespace:: 
         last_namespace:: // 3 
        last_namespace:: // 2 
       last_namespace:: // 1 
      last_namespace:: // oxford 
     last_namespace::alice::where_am_i // not the global namespace! 
     << ".. but I'd rather be " << ::alice::where_am_i // the global namespace. 
     << std::endl ; // There's no place like Uncle Charles' picnic blanket... but I'd rather be HOME! 

    std::cout << std::endl ; 
    return 0 ; 
} 


///// 
///// EOF 
///// 


/* Compiled with: 
    `g++ -std=c++11 -o alice alice.cpp` 
*/ 

/* Output of `alice` : 

There's no place like HOME! 
There's no place like needing a fix. 
There's no place like an empty rabbit hole. 

I'm late! 
I'm late, but I ditched that addled girl. 

There's no place like Uncle Charles' picnic blanket. 
There's no place like Uncle Charles' picnic blanket... but I'd rather be HOME! 

*/ 
+0

अंग्रेजी कृपया। शब्द "कोलन" है। –

+0

आप अपने वैश्विक दायरे में 'नेमस्पेस ऑब्जेक्टिव रीयलिटी का उपयोग करके' क्यों नहीं जोड़ सकते? C12+ नामस्थानों पर उत्सुकता से दार्शनिक लेने के लिए –

+2

+1। – nneonneo

उत्तर

2

मुझे नहीं लगता कि आप वैश्विक नामस्थान को उपनाम कर सकते हैं।

मानक स्पष्ट बजाय साथ :: बाहर बुलाया एक namespace उर्फ ​​परिभाषित करता है सिर्फ एक और नाम स्थान नाम है जैसे कि यह इलाज का:

7.3.2 Namespace alias 
A namespace-alias-definition declares an alternate name for a namespace according to the following grammar: 
namespace-alias: 
    identifier 
namespace-alias-definition: 
    namespace identifier = qualified-namespace-specifier ; 
qualified-namespace-specifier: 
    ::_opt nested-name-specifier_opt namespace-name 

नोट ऑप्ट (वैकल्पिक) है :: कि है, लेकिन नाम स्थान-नाम नहीं है ।

हालांकि, क्या आप अपने नामस्थान स्टैक की शुरुआत के रूप में वैश्विक नामस्थान के अलावा कुछ और नहीं उपयोग कर सकते हैं और अभी भी आपके द्वारा उल्लिखित पैटर्न का पालन कर सकते हैं?

यह भी ध्यान रखें आपके उदाहरण वास्तव में एक जोड़े को अतिरिक्त लाइनें संपादित जब आप ObjectiveReality हटाने की जरूरत होती है जो:

namespace current_authority = ObjectiveReality ; 

और:

<< ObjectiveReality::EntangledObserver::cat_is_alive::value 

यहाँ अपने उदाहरण नाम स्थान "कुछ" का उपयोग कर कैसा दिखता है अपने नामस्थान स्टैक की जड़ के रूप में वैश्विक नामस्थान की बजाय।

#include <iostream> 
#include <iomanip> 


// ...                                                                                          
namespace something { 
    using cat_is_alive = std::true_type ; // because I like cats                                                                            
} 
using namespace something; 
// ...                                                                                          


// ASIDE: I originally had `namespace higher_authority = COMPILER ;` as a comment, but changed it for simpler chaining closure                                                            

// The next two lines are the crux of my question...                                                                              

namespace higher_authority = something; 
namespace current_authority = something;                                                                           

// If the above two lines defined aliases for the (unnamed) global namespace, then the suggested elisions/replacements work...                                                            

/* -> */ 
namespace ObjectiveReality { 
    /* <- */ 
    // Simplest fix: replace with `using ObjectiveReality = current_authority ;`                                                                        
    // (Otherwise, a few other changes are necessary)                                                                              

    namespace higher_authority = current_authority ; 
    namespace current_authority = ObjectiveReality ; 

    using cat_is_alive = higher_authority::cat_is_alive ; 

    namespace EntangledObserver { 

    namespace higher_authority = current_authority ; 
    namespace current_authority = EntangledObserver ; 

    using cat_is_alive = higher_authority::cat_is_alive ; 
    } ; 
    /* -> */ 
} ; 
/* <- */ 


int main(int argc, char** argv) { 

    std::cout 
    << "It is " 
    << ObjectiveReality::EntangledObserver::cat_is_alive::value 
    << " that the cat is alive." << std::endl ; 

    return 0 ; 
} 


// EOF 
+0

आपने मुझे बुलाया। मैं वास्तव में 'cat_is_alive' को अपने पापों को अपमानित करने की कोशिश कर रहा हूं; मुझे आपके उम्मीदवार के जवाब को खत्म करना होगा, उदाहरण और व्याकरण दोनों के लिए धन्यवाद! इस बीच: क्या वैश्विक नामस्थान उपनाम _disallow_ करने का कोई कानूनी अस्तित्व है? –

+0

अभी भी उलझन - लेकिन जैसे, बाल्टी में एक छेद है। ऊपर सेवरमैन से, "... क्या आप अपने नामस्थान स्टैक की शुरुआत के रूप में वैश्विक नामस्थान के अलावा कुछ और नहीं कर सकते हैं और अभी भी आपके द्वारा उल्लिखित पैटर्न का पालन कर सकते हैं?" मेरी भव्य योजना एन = 1 बेस केस को ठीक करना है। n => n + 1 बहुत अच्छा है, लेकिन स्तर-का-अमूर्तता यहां समाधान नहीं है, है ना? –

+2

मुझे नहीं लगता कि वैश्विक नामस्थान को अलियासिंग रोकने के लिए कोई अस्तित्व [आईएसटी] कारण है। जहां तक ​​मैं कह सकता हूं कि जिस तरह से भाषा परिभाषित की गई है। कभी-कभी सी ++ थोड़ा बेतुका है [आईएसटी]। क्या आप समझा सकते हैं कि वैश्विक नेमस्पेस के बजाय नामित नेमस्पेस का उपयोग क्यों करें क्योंकि आपका एन = 1 बेस केस आपके परिदृश्य के लिए काम नहीं करता है? मैंने आपके स्तर-अमूर्त चिंता का पालन नहीं किया। – Soverman

2

मैं (यह मानते हुए आप मैक्रो का नाम असंबंधित प्रतीकों के साथ टकराने के साथ रहने के लिए तैयार हैं) एक तरह से सीधे डिफ़ॉल्ट नाम स्थान उर्फ, लेकिन एक समाधान के रूप में आप मैक्रो का उपयोग हो सकता है के बारे में पता नहीं कर रहा हूँ।

#define root_namespace 

उपयोग:

root_namespace::cat_is_alive 

राँभना बतख सही ढंग से बताते हैं, इस हैक using खंड के साथ काम नहीं करेगा।

+4

यह चालाक है, लेकिन ... 'नेमस्पेस root_namespace का उपयोग कर; ' –