【问题标题】:Can I undo the effect of "using namespace" in C++?我可以撤消 C++ 中“使用命名空间”的效果吗?
【发布时间】:2011-01-10 07:25:25
【问题描述】:

使用using namespace,我使该命名空间的全部内容直接可见,而无需使用命名空间限定符。如果using namespace 出现在广泛使用的标头中,这可能会导致问题 - 我们可能会无意中使两个具有相同类名的命名空间可见,并且编译器将拒绝编译,除非类名前面带有命名空间限定符。

我可以撤消 using namespace 以使编译器忘记它之前看到的吗?

【问题讨论】:

  • 我敢打赌,有一个非常丑陋的黑客为此使用了预处理器。但我猜你不想要那个
  • @Eli:Boost 中没有,这可能意味着没有。
  • 至少缩短您必须输入的内容的可能解决方案是在文件顶部使用#define N namespace::,在底部使用#undef N。当然,这意味着您必须小心不要在文件中您不希望出现namespace:: 的任何地方使用Ntypedef 也可能有用。

标签: c++ namespaces using


【解决方案1】:

据我所知...但通常我只在 .cpp 文件中使用“使用命名空间”。

【讨论】:

    【解决方案2】:

    不,但您可以告诉您的同事,您永远不应该在标题中包含 using 指令或声明。

    【讨论】:

    • 不幸的是,第三方库 (opencv.org/platforms/cuda.html) 需要这个,我们不能重写它。这看起来不像是一个答案,很多事情在生活中应该避免但却是不可避免的。
    【解决方案3】:

    正如其他人所说,您不能,而且问题首先不应该存在。
    您可以做的下一个最好的事情是引入您需要的符号,以便名称查找首选它们:

    namespace A { class C {}; }
    namespace B { class C {}; }
    using namespace A;
    using namespace B;
    
    namespace D {
        using A::C; // fixes ambiguity
        C c;
    }
    

    在某些情况下,您还可以使用命名空间来包装违规的包含:

    namespace offender {
    #  include "offender.h"
    }
    

    【讨论】:

    • 最后一种技术可能是一罐蠕虫。如果 offender.h 包含受 #define 保护的标头,那么现在这些符号会卡在 offender 中。您可以尝试将其整个接口包全面放在一个新的命名空间中,但仍然希望它不包含系统头文件。如果它工作一次,它可能会在下一个版本中中断。
    【解决方案4】:

    不,C++ 标准没有提及“撤消”。您可以做的最好的事情是限制using的范围:

    #include <vector>
    
    namespace Ximpl {
    
    using namespace std;    
    vector<int> x;
    
    }
    
    vector<int> z; // error. should be std::vector<int>
    

    但不幸的是,using namespace Ximpl 也会带来来自std 命名空间的所有名称。

    【讨论】:

      【解决方案5】:

      我将尝试在头文件中使用的最接近的如下:

      //example.h
      
      #ifndef EXAMPLE_H_
      #define EXAMPLE_H_
      
      
      /**
       * hating c++ for not having "undo" of using namespace xx
       */
      #define string std::string
      #define map std::map
      
      class Example {
      public:
          Example (const char *filename);
          Example (string filename);
          ~Example ();
      private:
          map<string,complicated_stuff*> my_complicated_map;
      
      };
      
      #undef string
      #undef map
      
      #endif //EXAMPLE_H_
      

      毕竟,定义是#undef -able。 有2个问题: 1.很丑 2. 分别使用对应命名空间中的每个名称的#define 和#undef

      【讨论】:

        猜你喜欢
        • 2012-03-06
        • 2015-07-21
        • 1970-01-01
        • 1970-01-01
        • 2023-03-26
        • 2016-03-02
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多