【问题标题】:Consistent approach for renaming namespaces in C++在 C++ 中重命名命名空间的一致方法
【发布时间】:2012-07-06 01:50:27
【问题描述】:

使用嵌套命名空间时,有时完全限定名称会变得很长。我知道我可以使用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;

目前我在每个翻译单元的基础上执行此操作,但我希望对整个项目使用全局方法。

【问题讨论】:

  • @close-voters 我不明白为什么这个问题没有建设性。在某些时候,SO 可能会变成一个只允许回答简短而明确的问题(例如“你忘记了分号”)的地方。不过,我希望这永远不会发生。
  • 我缺少的一点是,如果您愿意为每个长名称空间提供一个短名称,您为什么不首先这样做呢? (即为什么有一个复杂的命名空间层次结构和一个重新映射的平面列表)?我只认为别名命名空间对单个翻译单元有用(即在 .cpp 中,而不是在标题中)。
  • @betabandido:这不是短/长答案的问题,而是客观答案的问题。这个问题非常主观。有些人(像我一样)会更喜欢pcc,而不是像pr_cl_core 这样笨拙的名字,或者只是using project::client::core::OneClass;,而其他人会争论最好的名字采样方式(匈牙利语?)。因此,这个问题太难以辩论,无法具有建设性。
  • @MatthieuM。好吧,我不是在问哪个命名更好(pcc vs. pr_cl_core),而是如何在整个项目中从技术上实现这样的重命名。这不是主观的。可能有多种解决方案,但这是一个明确的目标,IMO。
  • @MatthieuM。我想说很多人会同意为整个项目命名一致的好处。我不明白你为什么要相反。

标签: c++ namespaces hierarchy


【解决方案1】:

我认为,如果您必须反复输入长名称空间名称,那么您的名称空间层次结构中就有问题。

假设您对类也有同样的情况,发现自己反复输入obj->sub()->subsub()->some_method()。这将违反Law of Demeter。在类的情况下,您将重构代码(通过编写包装函数),以便层次结构中的类只需要访问上一层的方法。

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

Boost 使用嵌套命名空间的事实只是部分正确,因为大多数嵌套命名空间如 auxdetail 不应该被客户端调用。例如。 Boost.MPL 是一个非常好的库示例,它注意不要无缘无故地暴露嵌套的命名空间。

【讨论】:

  • 假设我决定扁平化命名空间,所以我摆脱了这个问题。我将如何解决 Boost 中长名称空间的问题?我想避免输入boost::asio::ip::tcp::socket(或类似的东西)。
  • @betabandido Boost.Asio 确实有过长的命名空间命名。您至少可以尝试使用别名来隔离其中一些:namespace asio = boost::asio;,并且在使用 TCP/IP 套接字的低级代码中,您可以使用namespace socket = bost:asio::ip::tcp::socket;,例如
  • 这就是我现在正在做的事情。但我的问题是如何在项目中的所有源文件中以系统的方式进行重命名。以系统的方式这样做至少有两个潜在的优势:1) 减少输入量(尤其是在有多个重命名的情况下)和 2) 在整个项目中进行一致的重命名。
  • @betabandido 除了别名、typedefs 和重构你的层次结构之外,我认为你可能不得不依赖你的编辑器来完成语法完成(Intellisense 这些天很好)。
猜你喜欢
  • 2020-12-18
  • 1970-01-01
  • 2023-03-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-07-26
  • 2013-06-17
  • 1970-01-01
相关资源
最近更新 更多