2012-07-05 13 views
19

Cuando se utilizan espacios de nombres anidados, a veces los nombres totalmente calificados terminan siendo bastante largos. Sé que puedo usar namespace abc = aaa::bbb::ccc para reducir la cantidad de tipeo (también puede mejorar la legibilidad en algunos casos).Enfoque coherente para cambiar el nombre de espacios de nombres en C++

No estoy seguro, sin embargo, cuál es la mejor manera de lograr este cambio de nombre en todos los archivos de un proyecto. El enfoque directo (es decir, para cambiar el nombre de los espacios de nombres largos por usuario) podría llevar a utilizar diferentes nombres cortos para el mismo nombre completo en archivos diferentes. Entonces, estaba pensando en encontrar una forma más consistente de hacer esto.

Por ejemplo, vamos a suponer algo como:

project 
    |- client 
    | |- core 
    | |- plugin 
    | |- util 
    |- server 
     ... 

estaba pensando para crear un encabezado por directorio que incluye los nombres reducidos. Por ejemplo, project/client/core/core.h contendría namespace pr_cl_core = project::client::core (sé que el ejemplo para este nombre corto es bastante pobre, pero en proyectos reales tienen más sentido). Luego, incluiría core.h en todos los archivos de encabezado en project/client/core, de modo que cuando se incluye un encabezado de ese directorio en, digamos, project/client/plugin/plugin_foo.h, las versiones cortas del espacio de nombres estén disponibles.

¿Es este un buen enfoque para hacerlo? ¿Hay alguna otra forma mejor?

He encontrado varias preguntas sobre espacios de nombres C++ en SO (por ejemplo, 1 y 2), pero ninguna de ellas se relaciona con la forma de resolver el cambio de nombre del espacio de nombre en todo el proyecto.

EDIT: Además, un mecanismo de este tipo se podría utilizar para cambiar el nombre sistemáticamente de espacios de nombres largos (como los de Boost) para un proyecto completo. Por ejemplo, normalmente cambiar el nombre de algunos espacios de nombres como:

namespace ip = boost::asio::ip; 
namespace ptime = boost::posix_time; 

Actualmente hago esto sobre una base per-traducción unidad, pero me gustaría hacerlo mediante una estrategia global para todo el proyecto.

+0

Podría hacerlo, o podría hacerlo aún más simple: tener un encabezado en el nivel superior que declara prototipos para todos los espacios de nombres y los alias. Entonces solo incluye eso en los subdires. – Linuxios

+0

@Linuxios Estaba pensando algo así también, pero puede terminar presentando muchas dependencias: si cambiara ese archivo global, prácticamente todos los archivos del proyecto tendrían que volver a compilarse. Dicho eso, si la estructura de los espacios de nombres no cambia demasiado, no debería ser un problema importante. – betabandido

+0

@betabendido: Ah. ¿Qué pasa con la solución rápida y sucia? ¡Macros de preprocesador! Simplemente declare en cada archivo sus alias. De esta forma, cada archivo puede tener sus propios alias. Sí, la gente gritará por la duplicación del código, pero siempre puedes agregar un script de compilación para hacerlo por ti ... – Linuxios

Respuesta

1

Me atrevería a decir que si repetidamente tiene que escribir nombres largos de espacio de nombres, entonces algo está mal en su jerarquía de espacio de nombres.

Supongamos que tiene lo mismo con las clases, y se encuentra repetidamente escribiendo obj->sub()->subsub()->some_method(). Esto sería una violación del Law of Demeter. En el caso de las clases, debe refactorizar su código (escribiendo funciones de contenedor) para que las clases de la jerarquía solo tengan que acceder a los métodos un nivel arriba.

El mismo se debe hacer con los espacios de nombres: si tiene que llamar project::client::core entonces usted debe escribir funciones de contenedor/clases en client para exponer las interfaces necesarias para project. Si necesita hacer esto por todos lados, ¿por qué no aplanar su estructura de espacio de nombres para que client y core estén en el mismo nivel?

El hecho de que Boost usa el espacio de nombres anidado es parcialmente cierto, porque los clientes no deben llamar a la mayoría de los espacios de nombres anidados como aux y detail. P.ej. Boost.MPL es un muy buen ejemplo de una biblioteca que tiene cuidado de no exponer innecesariamente espacios de nombres anidados.

+0

Supongamos que decido aplanar el espacio de nombres, así que me deshago de ese problema. ¿Cómo resolvería el problema de los espacios de nombres largos de Boost? Me gustaría evitar escribir 'boost :: asio :: ip :: tcp :: socket' (o cosas similares). – betabandido

+0

@betabandido Boost.Asio tiene nombres de espacio de nombres excesivamente largos. Al menos puede tratar de aislar algo de eso con alias: 'namespace asio = boost :: asio;' y en el código de bajo nivel que usa sockets TCP/IP puede hacer 'namespace socket = bost: asio :: ip :: tcp :: socket; 'por ejemplo – TemplateRex

+0

Eso es realmente lo que estoy haciendo en este momento.Pero mi pregunta es cómo hacer ese cambio de nombre de una manera sistemática en todos los archivos fuente en un proyecto. Al menos hay dos ventajas potenciales de hacer eso de una manera sistemática: 1) menor cantidad de tipeo (especialmente si hay varias redefiniciones) y 2) un cambio de nombre consistente en todo el proyecto. – betabandido

Cuestiones relacionadas