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

c++ namespace best practice dilemma

本文关键字:困境 最佳 空间 c++      更新时间:2023-10-16

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

我的程序由几个不同的模块组成,这些模块大多内置于"主"应用程序使用的库中。每个库都使用自己的名称空间,它们的名称空间都在项目名称空间内,以帮助项目避免与第三方代码的名称冲突。所以我最后用类名,如"myproject::logging::Logger"answers"myproject::reporting::ReportType"(作为编造的例子)。

到目前为止一切顺利。在我的。cpp文件中,我没有问题。例如,我在顶部使用"using myproject::logging",并且可以清晰地引用我的logging类。在我的两个名称空间之间不太可能发生冲突的情况下,我只需显式地说明我想要哪个。

头文件是不同的。将using语句放入头文件中被认为是不好的做法,因为它们会影响不需要它们的不相关代码。所以我总是完全限定.hpp文件中的所有名称。这有点难看,但到目前为止还可以处理,所以我已经忍受了。但是现在我越来越多地在我的库中使用模板代码,这意味着现在在我的。hpp文件中有更多的实际代码。由于类型名称的长度,必须完全限定每个名称会使代码实际上不可读。

我开始觉得名称空间的好处和使用它们的最佳实践开始被我必须编写的代码的不可读性所抵消。我开始考虑放弃名称空间的使用是否更好,以获得更具可读性的代码的好处,并在出现名称冲突时修复它们。

另一种选择是使用简短的单层名称空间,这样我就可以用"log::Logger"代替"myproject::logging::Logger",这将有很大的帮助,但会使名称空间冲突的可能性高得多,并且名称空间传递的有用信息也会减少。

正如我所说的,这只会真正影响。hpp文件中的代码,因为我很高兴在我的实现文件中使用"使用名称空间"使其易于管理,但它成为一个问题,因为我现在在。hpp文件中查看我的模板代码,并认为"eww...."不可能是好的:p

谁有什么实用的建议?

我是这样做的

In <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;
  };
};

来源:

#include <mylibrary.h>
using namespace myproject::mylibrary; //clean!

我以前也遇到过这种情况。通常情况下,头文件中的许多模板函数/类都是真正的"实现",尽管根据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
但是,这种方法可能会扩大编译器报告中的名称。

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

个人?我会去掉"我的项目"这部分。您的库使用与另一个完全相同的名称空间名称并且具有与另一个名称定义的符号的可能性有多大?

另外,我建议在标题中使用更短的名称空间

我的经验是,由于您在原始帖子中提到的原因,为所有代码使用一个名称空间要方便得多。这个命名空间可以防止您的标识符与来自第三方库的标识符冲突。您的名称空间就是您的领地,因此很容易保持它没有名称冲突。

我使用以下方法来清除头文件中大量的std:::

// mylibrary.h
namespace myproject {
  namespace mylibrary {
    namespace impl {
      using namespace std;
      namespace stripped_std {
        // Here goes normal structure of your program:
        // classes, nested namespaces etc.
        class myclass;
        namespace my_inner_namespace {
                ...     
        }
       } // namespace stripped_std   
    } // namespace impl
  using namespace impl::stripped_std;
  } // namespace mylibrary
} namespace myproject

// Usage in .cpp file
#include <mylibrary.h>
using namespace myproject::mylibrary;

与n.m.的建议类似,但做了修改:还有一个辅助命名空间stripped_std。总体效果是using namespace myproject::mylibrary;行允许您引用内部名称空间结构,同时它不会将namespace std带入库用户的作用域。


很遗憾下面的语法

using namespace std {
...
}
在写这篇文章的时候

在c++中是无效的

如果你的项目不是非常非常非常大(我的意思是,非常大),只使用myproject应该是足够的。如果您确实希望将项目划分为多个部分,则可以使用更通用的名称空间。例如,如果我正在构建一个游戏引擎,我会使用MyEngine::Core、MyEngine::Renderer、MyEngine::Input、MyEngine::Sound等命名空间。