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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/6955023/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-28 21:01:30  来源:igfitidea点击:

c++ namespace best practice dilemma

c++namespaces

提问by jcoder

I'm finding that what I've considered "best practice" for use namespace in c++ is hurting the readability of my code, and making me question how to use them well.

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

My program consists of a few different modules which are mostly built into libraries that the "main" application uses. Each library uses it's own namespace, and their namespaces are all "inside" a project namespace to help project against name conflicts with 3rd party code. So I end up with class names such as "myproject::logging::Logger" and "myproject::reporting::ReportType" (As made up examples).

我的程序由几个不同的模块组成,这些模块主要内置在“主”应用程序使用的库中。每个库都使用自己的命名空间,它们的命名空间都在项目命名空间的“内部”,以帮助项目避免与 3rd 方代码的名称冲突。所以我最终得到了诸如“myproject::logging::Logger”和“myproject::reporting::ReportType”之类的类名(作为例子)。

So far so good. And in my .cpp files I have no problem. I use "using myproject::logging" at the top for example, and can cleanly refer to my Logging class. In the unlikely event of a conflict between two of my namespaces I can just explicitly say which one I want. This works well.

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

Header files are different though. It's considered bad practice to put using statements into header files as they will affect unrelated code that may not expect them. So I always fully qualify all the names in .hpp files. That was somewhat ugly but managable up to now so I've put up with it. But now I'm increasing using template code in my libraries which means that there is much moreactual code in my .hpp files now. And having to fully qualify every name is making the code practically unreadable due to the length of type names.

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

I'm starting to feel that the benefits of namespaces and best practice for using them are beginning to be outweighed by the unreadablilty of the code I'm having to write. I'm starting to wonder if I would be better abandoning the use of namespaces to gain the benefit of more readable code and fixing any name conflicts if and when they appear.

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

An alternative is to use short, single layer namespaces so instead of "myproject::logging::Logger" I would merely have "log::Logger" which would help a lot but make the likelyhood of namespace conflicts much higher, and also have the namespaces convey less useful information.

另一种方法是使用短的、单层的命名空间,而不是“myproject::logging::Logger”,我只会有“log::Logger”,这将有很大帮助,但会使命名空间冲突的可能性更高,并且还有命名空间传达的信息不太有用。

As I've said, this only really affects code in .hpp files as I'm happily using "using namespace" in my implementation files to make this manageable, but it isbecoming a problem as I look at my templated code in .hpp files now and think "eww...." which can't be good :P

正如我已经说过了,这是我高兴地用我的实现文件“使用命名空间”,以方便管理才真正影响.HPP文件中的代码,但它正在成为一个问题,因为我看看我的.HPP模板代码现在文件并认为“eww ....”这不太好:P

Anyone got any practical advice?

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

采纳答案by dsign

I have been in this situation before. It is often the case that a lot of template functions/classes in your headers are really "implementation", although by the nature of templates in C++ you are forced to put them in a header file. Thus, I just put everything in some "detail" or "implementation" namespace, where I can comfortably use "using namespace". At the end, I "drop" what people should use to the corresponding place. Like this:

我以前也遇到过这种情况。通常情况下,头文件中的许多模板函数/类实际上是“实现”,尽管由于 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

This approach might enlarge a bit the names on your compiler reports, though.

不过,这种方法可能会稍微放大编译器报告上的名称。

Alternatively, you can give up the modules namespaces. But it might not be a good idea for an extremely large project.

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

回答by n. 'pronouns' m.

Here's what I do.

这就是我所做的。

In <mylibrary.h>:

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

In the source:

在来源:

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

回答by Nicol Bolas

Personally? I'd get rid of the "myproject" part. What is the chance that your library will use the exact same namespace name as another andhave a symbol defined with the same name as another?

亲身?我会摆脱“myproject”部分。什么是你的图书馆将使用完全相同的命名空间的名称作为另一个机会,并具有相同的名称作为另一定义的符号?

Also, I would suggest shorter names for namespaces you expect to be used in headers.

另外,我会建议您希望在标题中使用的命名空间更短的名称。

回答by Maxim Egorushkin

My experience have been that it is much more convenient to have one namespace for all your code for the reasons you mentioned in your original post. This namespace protects your identifiers from clashing with identifiers from 3rd-party libraries. Your namespace is your dominion and it is easy to keep it name-conflict-free.

我的经验是,由于您在原始帖子中提到的原因,为所有代码使用一个命名空间要方便得多。此命名空间可保护您的标识符免于与来自 3rd 方库的标识符发生冲突。您的命名空间是您的领地,并且很容易保持名称无冲突。

回答by Fedorov7890

I use the following to get rid of enormous amounts of std::in header file:

我使用以下方法去除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;

It is similar to what was suggested by n.m., but with a modification: there is one more auxiliary namespace stripped_std. The overall effect is that line using namespace myproject::mylibrary;allows you to refer to the inner namespace structure, and at the same time it does not bring namespace stdinto library user's scope.

它类似于 nm 的建议,但有一个修改:还有一个辅助名称空间stripped_std。总体效果是该行using namespace myproject::mylibrary;允许您引用内部命名空间结构,同时它不会带namespace std入库用户的范围。



It's a pity though that the following syntax

遗憾的是,以下语法

using namespace std {
...
}

is not valid in C++ at the time when this post is written.

在撰写本文时,在 C++ 中无效。

回答by holgac

If your project isn't very very very huge (I mean, very huge), using only myproject should be sufficent. If you really want to divide your project into parts, you can use more generalized namespaces. For example, if I was building a game engine, I would go for namespaces like MyEngine::Core, MyEngine::Renderer, MyEngine::Input, MyEngine::Sound etc.

如果您的项目不是非常非常非常庞大(我的意思是非常庞大),那么仅使用 myproject 就足够了。如果你真的想把你的项目分成几个部分,你可以使用更通用的命名空间。例如,如果我正在构建一个游戏引擎,我会选择 MyEngine::Core、MyEngine::Renderer、MyEngine::Input、MyEngine::Sound 等命名空间。