c++ - que - using namespace std error
Cómo alias el espacio de nombre global en C++ 11 (2)
No creo que pueda alias el espacio de nombres global.
El estándar define un alias de espacio de nombres con :: llamado explícitamente en lugar de tratarlo como solo otro nombre de espacio de nombres:
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
Tenga en cuenta que :: es opt (opcional), pero el namespace-name no lo es.
Sin embargo, ¿no podría simplemente usar algo que no sea el espacio de nombre global como el inicio de su pila de espacio de nombres y aún seguir el patrón que ha delineado?
También tenga en cuenta que, de hecho, su ejemplo necesita un par de líneas adicionales editadas cuando elimina ObjectiveReality:
namespace current_authority = ObjectiveReality ;
y:
<< ObjectiveReality::EntangledObserver::cat_is_alive::value
Este es el aspecto de su ejemplo al usar el espacio de nombres "algo" en lugar del espacio de nombres global como la raíz de su pila de espacio de nombres.
#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
Forma corta : ¿Cómo puedo definir un alias para el espacio de nombres raíz (global) en C ++ 11? Puede parecerse
namespace root_namespace = :: ;
donde el operador de resolución de alcance en su forma desnuda arriba es un marcador de posición para algún manejador del espacio de nombre global. Leí en el Manual de GCC Internals que
... La raíz de la representación intermedia completa del [compilador] es la variable global_namespace. Este es el espacio de nombres especificado con ::
en el código fuente de C ++ ... El nombre del espacio de nombres global es ::
, aunque en C ++ el espacio de nombres global no tiene nombre.
EDITORIAL : para los encuestados hasta la fecha, agregué una larga y dolorosa forma para abordar algunas inquietudes después de la siguiente forma larga , ya que puede aclarar algunas cosas. Y seguidores, si nos ves hablando en lugar de uno con el otro, atrévete.
Forma Larga : Un ejemplo de su uso potencial sigue. Si no es satisfactorio, entonces sí, esta es una pregunta académica; ver la forma dolorosamente larga que sigue a esta.
Imagina que tu jefe irrumpe en un día y dice: "Acabo de leer un libro sobre el pospositivismo. Deshazte del namespace ObjectiveReality
de namespace ObjectiveReality
". En el siguiente código, ''todo'' lo que tienes que hacer es omitir las líneas que he marcado como /* -> */
this /* <- */
. Puedes hacer eso para niveles intermedios de anidación actualmente; sin embargo, no estoy seguro de cómo definir el namespace current_authority
ámbito global namespace current_authority
para permitir la elisión simple del primer espacio de nombres no global.
#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
En caso de que se necesite información del compilador:
$ 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)
FORMA DOLOROSAMENTE LARGA : como respuesta a algunas respuestas sobre "comenzar desde un espacio de nombres anidado", tenga en cuenta que ''¡HOGAR!'' es inaccesible, y que no puedo darme el lujo de elegir a mano espacios de nombres en un equipo.
//
// 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!
*/
No conozco una forma de aliar directamente el espacio de nombres predeterminado, pero como solución alternativa puede usar una macro (suponiendo que esté dispuesto a vivir con el nombre de la macro colisionando con símbolos no relacionados).
#define root_namespace
Uso:
root_namespace::cat_is_alive
Como Mooing Duck señala correctamente, este hack no funcionará con el using
cláusulas.