c ++命名空间头痛

时间:2009-12-14 18:33:33

标签: c++ namespaces

5 个答案:

答案 0 :(得分:6)

我不认为这里不必限定命名空间范围free(),但应该注意这与“绝对路径”不同。首先,如果你有嵌套的命名空间,你只需要引用最里面的命名空间:

namespace N1 {
  namespace N2 {
    namespace N3 {
      void free(THING * thing);

      class C {
      public:
        free() {
          N3::free(m_Thing); // no need to do N1::N2::
        }
      };
    }
  }
}

[编辑] 以回应编辑过的问题。同样,我没有看到任何方法在您描述的确切场景中执行此操作。但是,它似乎不是惯用的C ++方法 - 更常见的方法是为ITEMIDLIST提供管理所有分配,RAII样式和暴露原始句柄的自己的包装类(例如,通过转换运算符a la ATL,或者如果你想要额外的安全性,可以使用像c_str()这样的显式成员函数。这将完全取消对free的需求,并且对于您可能需要的任何其他免费函数,因为您控制了包装类型和它所在的命名空间,您可以像往常一样使用ADL。

[编辑#2] 。这部分问题:

  

允许直观和有用的名称解析,如果我的代码在他们的NS中但由我的代码的客户端明确地引入(即我不想无缘无故地注入我的代码,但仅根据明确要求)?

这不正是你把它放在命名空间中,而你的客户写作using namespace ...会不会实现呢?

答案 1 :(得分:5)

您有两种选择:

  1. 完全限定功能名称。
  2. Koenig lookup完成工作(如果THING属于名称空间N)。
  3. 我会选择第一个具有如free这样的流行函数名称。

    替代选项是使用m_thing->Release()或类似的东西。

答案 2 :(得分:0)

Yuu可以写::free(m_thing);。这将调用全局free()函数。但是,如果你在N命名空间之外有另一个free()函数,那么你就遇到了麻烦。要么更改某些函数的名称,要么使用带有显式名称空间的函数名称。

答案 3 :(得分:0)

我会使用一种完全不同的方法来实现你想要完成的任务。我想你需要重新设计一下。删除全局变量并创建一个工厂/抽象工厂,它将构造(创建类的实例)并使用析构函数将其销毁。事实上,这将是RAII的习语。

答案 4 :(得分:0)

在我看来,这里存在设计问题。

我发现使用相同的标识符作为自由函数和类方法都很奇怪,它确实令人困惑。尽管我承认它发生在swap ...

,但我尽量尽量减少出现的次数。

我尽量不对方法中的名称进行限定,但当然这会冒hiding的风险,其中MyClass::free隐藏N::free方法,该方法从不参与查找...试图在这里找到范围解决方案,但找不到确切的段落。

对于交换我只需使用:

class MyClass
{
  void swap(MyClass& rhs)
  {
    using std::swap;         // Because int, etc... are not in std
    swap(m_foo, rhs.m_foo);
    swap(m_bar, rhs.m_bar);
  }
};

inline void swap(MyClass& lhs, MyClass& rhs) { lhs.swap(rhs); }

因此,我确保在查找中包含正确的方法,并避免使用'全局'方法(如果有的话)。

我更喜欢这种方法来显式命名,并且通常在方法的顶部添加usingtypedef声明,以便实际代码不会膨胀。