【问题标题】:Is there any way to avoid fully-specified class-names in a header without namespace pollution?有没有办法避免在没有命名空间污染的情况下在头文件中完全指定的类名?
【发布时间】:2021-09-30 12:00:44
【问题描述】:

我们有很多不在任何命名空间中的类,它们广泛使用 std。

例如:

class MyClass
{
std::map<std::string,std::vector<std::string>> mLookup
...

这很乏味,但因为它是一个标题,我不能只做using namespace std;,否则我会造成严重的污染。

我也不能(我认为)将这个类移动到一个新的命名空间中,而不必在代码库的其余部分中对它的每次使用进行更新,这一切都开始成为一项严肃的任务。

所以我想检查一下,C++(17) 提供任何其他解决方案吗?我只需要完全指定事物或引入命名空间?

【问题讨论】:

  • 17 或更高版本的编译器允许以下内容: " #include using std::cout, std::cerr, std::endl, std::hex, std::dec; ”。在此包括以下,您可以以这种更简单的形式使用 cout、cerr、endl、hex 和 dec 函数(不带 std:: 前缀),它还可以防止 的许多其他 std:: 函数污染您的编译跨度>
  • 编译器允许这些语句的时间比 C++17 长 很多
  • 这仍然会污染我use 的东西,对吧? using 中的 something.h 将被带到任何带有 #include something.h 的源/标头?这是一种改进,我同意。
  • 从C++11开始,你可以在类定义中使用别名声明(例如using mymap = std::map&lt;std::string,std::vector&lt;std::string&gt;&gt;,然后在MyClass中声明mymap mLookup。在类之外,该类型别名可以是像任何嵌套类型一样使用(例如MyClass::mymap a_map = some_object.mLookup)。
  • @peter 这可能是我正在寻找的答案!

标签: c++ stl


【解决方案1】:

不,如果您满足以下条件,则不必更改所有内容:

  1. 有一个你希望移动到特定命名空间的类的集合

  2. 您的代码组织良好,这些类在它们自己的、不同的翻译单元中实现,与所有其他类分开。

唯一需要做的事情:

A) 在您的头文件中,只需将类移动到它们自己的命名空间声明中:

#ifndef myclass_h
#define myclass_h

namespace app {   // start of namespace declaration
#if 0
}
#endif

class MyClass {
public:
    MyClass();

// ...

#if 0
{
#endif
}          // End of namespace declaration

#endif

这个预处理器技巧甚至消除了重新缩进所有内容的需要,并且愚弄了语法感知代码编辑器,使其不添加额外的缩进级别。从MyClass 到被移植到新命名空间中的其他类的所有引用也会一起更新(前提是它们的头文件以相同的方式调整)。

B) 最后,每个翻译单元都会做同样的事情。

#include "myclass.H"

namespace app {
#if 0
}
#endif

MyClass::MyClass()
{
   /// ...


#if 0
{
#endif
}

现在,只需键入几分钟,您就可以将一堆类移动到一个新的命名空间中。

附:几年后,您的手指会自动输入“std::”,而您甚至都没有意识到这一点,因此这不会成为问题。

【讨论】:

  • “有一个你希望移动到特定命名空间的类的集合”——这就是重点,我没有。我们有 数千个 类/文件。必须更改每个引用 something.h 的文件正是我想要避免的!
  • 那么,这就是脚本的用途。我还有一个包含数千个文件的库。有时我不得不进行大规模的改变。经过一番思考,我编写了一个完成 99% 工作的 Perl 脚本。任务完成。
  • 除了每个被修改的文件都必须在 PR 中进行审查。让自己受欢迎的好方法,除非你能获得审查工具来忽略这种微不足道的重构(?)
  • 嗯?在工作不受欢迎的组织中,这可能很容易避免。什么也不做。如果你不知道怎么做,那就向 Dilbert 的 Wally 学习。
  • 在 Stackoverflow 上获得好的答案的最佳方法是完整地解释问题,并包含 所有 相关细节。否则人们会花时间写一个答案,结果却发现根本没有提到一些相关的东西,而是一个问题。虽然我还有一些建议,但我担心他们最终会在同一条船上:“对不起,但是因为我现在第一次提到的 X,这对我不起作用”。可以说:在 C++ 中的某个地方没有可以自动重新命名空间类的魔术按钮。改变一切是不可避免的。
【解决方案2】:

进一步看,简短的回答是:不。

您可以在头文件中定义的方法或函数中使用using a::b::c,当然您也可以在 .cpp 文件中使用命名空间,但没有办法在不污染代码库的情况下在头文件中执行此操作。

正确的方法是将事物移入名称空间,但问题特别要求替代方案......似乎真的没有。编写新代码以避免将来出现这种陷阱的教训”

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-05-14
    • 1970-01-01
    • 1970-01-01
    • 2023-04-03
    • 2015-03-05
    相关资源
    最近更新 更多