命名空间root_namespace = ::;
其中以上述裸体形式的范围解析运算符是全局命名空间的一些句柄的占位符.我在GCC Internals Manual读了
… [编译器]整个中间代表的根是变量global_namespace.这是在C源代码中使用::指定的命名空间…全局命名空间的名称为::,即使在C中,全局命名空间未命名.
PS编辑:对于迄今为止的受访者,我附上了一个痛苦的长表格,以解决以下长表格之后的一些问题,因为它可能会澄清一些事情.和追随者,如果你看到我们说话而不是彼此,挖掘.
长形式:其潜在用途的一个例子如下.如果不能令人满意,那么是的,这是一个学术问题;看到这一个痛苦的长长的形式.
想象一下,你的老板有一天会驳船,并说:“我只是读了一本关于后实证主义的书,摆脱了命名空间ObjectiveReality.”在下面的代码中,你需要做的就是省略我所标记的行/ * – > * / this / *< - * /.你可以这样做当前的中间嵌套级别;然而,我不确定如何定义全局范围命名空间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)
PAINFULLY LONG FORM:作为对“从嵌套命名空间开始”的一些答案的回应,请注意“HOME!”是无法访问的,我可能没有在一个团队中选择手工命名空间的奢侈品.
// // 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! */
解决方法
该标准定义了一个命名空间别名,其中::被明确声明,而不是像另一个命名空间名称一样处理它:
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
注意::是opt(可选),但是namespace-name不是.
但是,您是否只能使用除全局命名空间之外的其他名称作为命名空间堆栈的开始,并且仍然遵循您概述的模式?
还要注意,您的示例实际上需要在删除ObjectiveReality时编辑的其他几行:
namespace current_authority = ObjectiveReality ;
和:
<< ObjectiveReality::EntangledObserver::cat_is_alive::value
以下是您的示例,使用命名空间“something”而不是全局命名空间作为命名空间堆栈的根.
#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