在C++中重命名命名空间的一致性方法

19

在使用嵌套命名空间时,有时完全限定名称会变得相当长。我知道可以使用namespace abc = aaa::bbb::ccc来减少键入量(这也可能在某些情况下提高可读性)。

然而,我不确定在整个项目中实现此重命名的最佳方法是什么。直接的方法(即按使用基础重命名长命名空间)可能会导致在不同文件中为相同的完全限定名称使用不同的短名称。因此,我考虑采用更一致的方法来完成此操作。

例如,假设像这样:

project
  |- client
  |   |- core
  |   |- plugin
  |   |- util
  |- server
      ...
我打算为每个目录创建一个包含缩短名称的头文件。例如,project/client/core/core.h 将包含 namespace pr_cl_core = project::client::core(我知道这个简短名称的示例比较差,但在实际项目中,它们更有意义)。然后,我会将 core.h 包含到 project/client/core 中所有头文件中,以便在包含该目录下的头文件时,例如在 project/client/plugin/plugin_foo.h 中,可以立即使用缩短的命名空间版本。
这是一种好的做法吗?还有其他更好的方法吗?
我在SO上找到了一些关于C++命名空间的问题(例如12),但没有一个与如何以项目范围的方式解决命名空间重命名相关。
编辑:此外,这样的机制可以用于对整个项目进行长命名空间的系统重命名(例如 Boost 的命名空间)。例如,我通常会将一些命名空间重命名为:
namespace ip = boost::asio::ip;
namespace ptime = boost::posix_time;

目前我是在每个翻译单元上这样做,但我希望能够使用全局方法来处理整个项目。


20
@close-voters 我不明白为什么这个问题被认为不够具有建设性。在某些时候,SO可能会成为只允许短而清晰的答案(例如“你忘记了分号”)的地方。尽管如此,我希望这种情况永远不会发生。 - betabandido
8
我不明白的是,如果你愿意为每个长命名空间提供一个简短的名称,为什么不一开始就这么做呢?(即为什么要有复杂的命名空间层次结构和重新映射的平面列表)我认为只有在单个翻译单元(即在 .cpp 文件中而不是头文件中)内部使用别名命名空间才有用。 - David Rodríguez - dribeas
1
@betabandido:这不是简短或长篇回答的问题,而是客观答案的问题。这个问题非常主观。有些人(比如我)会更喜欢pcc而不是像pr_cl_core这样笨重的名称,或者只是使用using project::client::core::OneClass;,而其他人则会争论最佳的命名方式(匈牙利命名法?)。因此,这个问题过于争议性,无法建设性地讨论。 - Matthieu M.
1
@MatthieuM。好的,我不是在问哪个命名更好(pcc vs. pr_cl_core),而是如何在整个项目中实现这样的重命名。这并不是主观的。可能有几种解决方案,但在我看来,这是一个明确的目标。 - betabandido
1
@MatthieuM。我认为很多人都会同意整个项目使用一致的命名有益处。我不明白为什么你想要相反的做法。 - betabandido
显示剩余8条评论
1个回答

1

我认为,如果您反复输入长命名空间名称,则说明您的命名空间层次结构存在问题。

假设您在类中也有同样的情况,反复输入obj->sub()->subsub()->some_method()。这将违反德米特法则。在类的情况下,您应该重构代码(编写包装器函数),以便位于层次结构下方的类只能访问上一级的方法。

对于命名空间,也应该采取同样的做法:如果您必须调用project::client::core,那么您应该在client中编写包装器函数/类,以向project公开必要的接口。如果您需要在各个地方都这样做,为什么不扁平化您的命名空间结构,使clientcore处于同一级别?

Boost使用嵌套命名空间的事实只是部分正确的,因为大多数像和这样的嵌套命名空间不应该由客户端调用。例如,Boost.MPL是一个非常好的库示例,它小心翼翼地不会毫无必要地暴露嵌套命名空间。

假设我决定展平命名空间,这样就解决了那个问题。那么我该如何解决Boost中长命名空间的问题? 我想避免输入 boost::asio::ip::tcp::socket(或类似的东西)。 - betabandido
@betabandido Boost.Asio确实有过长的命名空间。你可以尝试使用别名来隔离一些内容:namespace asio = boost::asio;,在使用TCP/IP套接字的低级代码中,你可以这样做:namespace socket = bost:asio::ip::tcp::socket; 例如: - TemplateRex
这实际上是我现在正在做的事情。但我的问题是如何以系统化的方式在项目中的所有源文件中进行重命名。至少有两个潜在的好处:1)减少打字量(特别是如果有多个重命名),2)整个项目中的一致性重命名。 - betabandido
除了别名、typedefs和重构你的层次结构,我认为你可能还需要依赖编辑器来进行语法补全(Intellisense这些天来相当不错)。 - TemplateRex

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接