c ++命名空间最佳实践困境

jco*_*der 26 c++ namespaces

我发现我认为在c ++中使用命名空间的"最佳实践"会损害我的代码的可读性,并让我质疑如何很好地使用它们.

我的程序由几个不同的模块组成,这些模块主要构建在"主"应用程序使用的库中.每个库都使用它自己的命名空间,它们的命名空间都在项目命名空间的"内部",以帮助预测与第三方代码的名称冲突.所以我最终得到了类名,例如"myproject :: logging :: Logger"和"myproject :: reporting :: ReportType"(作为例子).

到现在为止还挺好.在我的.cpp文件中我没有问题.我在顶部使用"使用myproject :: logging",并且可以干净地引用我的Logging类.如果我的两个命名空间之间发生冲突,我可以明确地说出我想要的那个.这很好用.

头文件虽然不同.将使用语句放入头文件中被认为是不好的做法,因为它们会影响可能不期望它们的不相关代码.所以我总是完全限定.hpp文件中的所有名称.到目前为止,这有点难看但是可以管理,所以我忍受了.但现在我正在增加在我的库中使用模板代码,这意味着现在我的.hpp文件中有更多的实际代码.由于类型名称的长度,必须完全限定每个名称使得代码几乎不可读.

我开始觉得命名空间的好处和使用它们的最佳实践开始被我不得不写的代码的不可读性所抵消.我开始怀疑我是否会更好地放弃使用命名空间来获得更易读的代码的好处,并在它们出现时修复任何名称冲突.

另一种方法是使用短的单层命名空间,而不是"myproject :: logging :: Logger",我只会使用"log :: Logger",它可以帮助很多,但会使命名空间冲突的可能性更高,而且还有命名空间传达的有用信息较少.

正如我所说,这只会影响.hpp文件中的代码,因为我很乐意在我的实现文件中使用"using namespace"来使这个可管理,但是当我在.hpp中查看我的模板化代码时它成为一个问题.文件现在并认为"eww ...."这不可能是好的:P

有人有任何实用的建议吗?

n. *_* m. 22

这就是我的工作.

<mylibrary.h>:

namespace myproject {
  namespace mylibrary
  {
    namespace impl
    {
      using namespace otherlibrary;
      using namespace boost;
      using namespace std;
      using namespace whatever::floats::your::boat;

      class myclass;
      class myotherclass;
    };
    using impl::myclass;
    using impl::myotherclass;
  };
};
Run Code Online (Sandbox Code Playgroud)

在来源:

#include <mylibrary.h>
using namespace myproject::mylibrary; //clean!
Run Code Online (Sandbox Code Playgroud)


dsi*_*ign 20

我之前一直处于这种状况.通常情况下,标题中的许多模板函数/类实际上都是"实现",尽管由于C++中模板的性质,您不得不将它们放在头文件中.因此,我只是将所有内容放在一些"详细信息"或"实现"命名空间中,我可以轻松地使用"使用命名空间".最后,我"贬低"人们应该使用的东西到相应的地方.像这样:

namespace myproject { namespace somemodule {

namespace _implementation {

using namespace myproject::othermodule;
using namespace myproject::yetanothermodule;

template <...>
class some_internal_metafunction{
...
};

template <...>
class stuff_people_should_use_outside {
...
};

} // namespace implementation       

using stuff_people_should_use_outside ;
}} // namespace myproject::somemodule
Run Code Online (Sandbox Code Playgroud)

但是,这种方法可能会扩大编译器报告中的名称.

或者,您可以放弃模块名称空间.但对于一个非常大的项目来说,这可能不是一个好主意.

  • 是否需要`使用_implementation :: stuff_people_should_use_outside;`? (3认同)

Nic*_*las 5

亲身?我摆脱了"myproject"部分.您的库将使用与另一个完全相同的命名空间名称并且具有与另一个名称相同的符号定义的可能性是多少?

此外,我建议您希望在标头中使用的命名空间的名称更短.

  • "对于给定的例子,`logging :: Logger`,你的库有可能使用完全相同的命名空间名称和另一个用同一名称定义的符号",我说机会很高世界上有两个.任何试图在一个程序中使用这两个库的人都不太可能,但是概率`:: myproject :: Logger`比`:: logging :: Logger`更安全(假设"myproject"被替换为项目的实际名称) ,ofc). (8认同)