Краткая форма: Как я могу определить псевдоним для корневого (глобального) пространства имен в C ++ 11? Это может выглядеть как
namespace root_namespace = :: ;
где оператор разрешения области видимости в его приведенной выше форме является заполнителем для некоторого дескриптора глобального пространства имен. Я читаю в GCC Internals Manual тот
…Корнем всего промежуточного представления [компилятора] является переменная global_namespace. Это пространство имен, указанное с ::
в исходном коде C ++ … Имя глобального пространства имен ::
, хотя в C ++ глобальное пространство имен не названо.
PS РЕДАКТИРОВАТЬ: к респондентам на сегодняшний день я приложил мучительно длинная форма решить некоторые проблемы после следующего длинная форма, с тех пор может уточнить некоторые вещи. И последователи, если вы видите, что мы разговариваем, а не друг с другом, копайтесь.
Длинная формаПример его потенциального использования приведен ниже. Если неудовлетворительно, то да, это академический вопрос; увидеть мучительно длинная форма что следует за этим.
Представьте, что ваш босс в один прекрасный день баржет и говорит: «Я только что прочитал книгу о постпозитивизме. Избавьтесь от namespace ObjectiveReality
Msgstr «В приведенном ниже коде все, что вам нужно сделать, это опустить строки, которые я пометил как /* -> */
этот /* <- */
, Вы Можно сделать это для промежуточных уровней вложенности в настоящее время; Однако я не уверен, как определить глобальный охват 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)
БЕЗУМНО ДОЛГО ФОРМА: в ответ на некоторые ответы о «начать с вложенного пространства имен» обратите внимание, что «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
Обратите внимание, что :: является опцией (необязательно), а 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
Я не знаю способа прямого псевдонима пространства имен по умолчанию, но в качестве обходного пути вы можете использовать макрос (при условии, что вы готовы жить с именем макроса, сталкивающимся с несвязанными символами).
#define root_namespace
Использование:
root_namespace::cat_is_alive
Как правильно указывает Mooing Duck, этот хак не будет работать с using
статьи.