2013-02-07 12 views
11

ショートフォーム:C++ 11のルート(グローバル)名前空間のエイリアスを定義するにはどうすればよいですか?それは裸の形でのスコープ解決演算子が上記のグローバル名前空間のいくつかのハンドルのプレースホルダーですC++ 11のグローバル名前空間のエイリアス方法

namespace root_namespace = :: ;

のように見えるかもしれません。 GCC Internals Manualその中で読む

... [コンパイラの]全体の中間表現のルートは変数global_namespaceです。これはC++ソースコードで::で指定された名前空間です...グローバル名前空間の名前は::ですが、C++ではグローバル名前空間の名前は変更されていません。

PS EDIT:最新の回答者に、私はそれいくつかのことを明確にするために、以下の長い形式後にいくつかの懸念に対処するためのpainfuly長い形式を追加。 。そして、あなたは私たちではなく、相互にで話を見れば、掘る信者、


ロングフォーム:その潜在的な使用の例は、以下。満足できない場合は、はい、これは学問的質問です。これに続くの痛いほど長い形を参照してください。

あなたの上司が一日でバージンして、「私はちょうどポスト・ポジティブ主義についての本を読んで、namespace ObjectiveRealityを取り除いてください」と言うことを想像してください。下のコードでは、あなたがしなければならない「すべて」は、/* -> */のようにマークした行を省略することです。/* <- */です。あなたはが可能です。は、現在中ぐらいのレベルのネスティングについてそうしています。しかし、グローバルスコープnamespace current_authorityを定義して、最初の非グローバルな名前空間を簡単に削除できるようにする方法は不明です。

$ 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) 

を痛いほどLONG FORM::HOME」という点に注意してください "ネストされた名前空間から始める" についてのいくつかの答えへの応答として、ケースコンパイラ情報が必要とされて

#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 

! '私はチーム内で名前空間を手に取るという贅沢を持っていないかもしれません。

// 
// 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

グローバルスコープに 'using namespace ObjectiveReality;'を追加できないのはなぜですか? –

+2

+1は奇妙なことに哲学的にC++ネームスペースを取ります。 – nneonneo

答えて

2

グローバルな名前空間のエイリアスはありません。 :: OPT(オプション)ですが、名前空間の名前ではないこと

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 

注:

標準はちょうど別の名前空間の名前のようにそれを治療するための明示的に代わりに::アウトと呼ばれる名前空間のエイリアスを定義します。

しかし、グローバル名前空間以外の名前空間を名前空間スタックの先頭に使用して、あなたが概説したパターンに従うことはできませんでしたか?

namespace current_authority = ObjectiveReality ; 

と::

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

ここにあなたの例では、名前空間「何か」を使用して次のようになります

はまた、あなたの例では、実際にあなたがObjectiveRealityを削除すると編集したカップル追加の行を必要とすることはないことに注意してくださいあなたの名前空間スタックのルートとしてグローバルな名前空間の代わりに。

#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'を私の不正を難読化しようとしているタイプとして書き換えました。私は、あなたの候補者の回答を、文法と例の両方に感謝しなければならないでしょう!同時に、グローバルな名前空間エイリアスを拒否する正当な理由がありますか? –

+0

まだ混乱していますが、バケツに穴があります。上のSovermanから、 "...あなたは名前空間スタックの始まりとしてグローバルな名前空間以外のものを使って、あなたが概説したパターンに従いますか?私の壮大な計画は、n = 1の基底の場合を修正することです。 n => n + 1は素晴らしいですが、抽象レベルはここでの解決策ではありませんか? –

+2

グローバルな名前空間のエイリアシングを防止するための存在理由[ist]はないと思います。限り、私はそれが言語が定義されている方法であることがわかります。ときには、C++はちょっとばかげた[ist]です。シナリオでn = 1の基本ケースが機能しないため、グローバル名前空間の代わりに名前付き名前空間を使用する理由を説明できますか?私はあなたの抽象レベルの懸念に従わなかった。 – Soverman

2

私が直接、デフォルトの名前空間のエイリアスへの道を認識してないんだけど、回避策として、あなたは(あなたがマクロの名前は無関係なシンボルと衝突と一緒に暮らすために喜んでいると仮定して)マクロを使用する場合があります。

#define root_namespace 

は使用方法:

root_namespace::cat_is_alive 

Mooingダックが正しく指摘するように、このハックはusing節では動作しません。

+4

これは賢いですが、... using namespace root_namespace; –

関連する問題