好的,这个问题有所发展,我想尝试着(从)开始为我所追求的基本目标:
我经常遇到这种情况,并且正在寻找更好的方法...
我在命名空间N中有一个类C。C有一个成员Free。它释放了C所管理的东西,并允许C来管理新事物。
有几个全局Free功能。在与C相同的命名空间N中也有一些辅助函数,其中之一是一个释放由C管理的东西的助手,名为free。
所以我们有这样的东西:
namespace N {
void free(THING * thing);
class C
{
public:
... details omitted...
free()
{
free(m_thing); // <- how best to refer to N::free(THING&)
}
}
} // namespace N
我可以使用N::free(m_thing)。但这对我来说很不幸。有没有办法引用超出类范围但没有解决绝对 namespace 的问题(从范围的角度出发相对一步)?
在我看来,必须将N::free命名是令人讨厌的,因为如果这是一个独立的函数,则不必这样做。如果类的方法名称碰巧是不同的(例如,dispose),则也不需要。但是,因为我使用了相同的名称,所以如果您不喜欢类比的话,就必须指定绝对路径而不是相对路径才能访问它。
我讨厌绝对的道路。它们使在 namespace 中移动东西变得非常脆弱,因此代码重构变得更加难看。另外,在函数主体中如何命名事物的规则随着当前的规则集(据我所知)变得更加复杂-不那么规则-导致人们期望与程序员之间达成 split 。
是否有更好的方法可以在与类相同的 namespace 中访问独立函数,而不必绝对命名自由函数?
编辑:
也许我应该举一个不太抽象的例子:
namespace Toolbox {
namespace Windows {
// deallocates the given PIDL
void Free(ITEMIDLIST ** ppidl);
class Pidl
{
public:
// create empty
Pidl() : m_pidl(NULL) { }
// create a copy of a given PIDL
explicit Pidl(const ITEMIDLIST * pidl);
// create a PIDL from an IShellFolder
explicit Pidl(IShellFolder * folder);
...
// dispose of the underlying ITEMIDLIST* so we can be free to manage another...
void Free();
};
因此,ITEMIDLIST *来自各个地方,并被CoTaskMemFree()销毁。我可以将Pidl引入为全局名称-以及工具箱库中的“Windows Shell.h” header 中的所有辅助函数。
理想情况下,我将库中的某些工具按它们所关联的内容进行 segmentation -在这种情况下,以上所有内容均与Windows中的COM编程有关。我已经选择了Toolbox作为我的库东西的基本命名空间,并且目前正在考虑使用Windows -y函数,类等Toolbox::Windows。
但是C++命名空间和名称解析规则似乎使这一点变得非常困难(因此出现了这个问题)。创建代码的这种分段非常不自然-因为koenig查找失败(因为ITEMIDLIST不在我的Toolbox::Windows命名空间中),并且我无法将其移到那里!我也不应该。该语言应该足够灵活,IMO,以允许扩展库(例如我的Toolbox库)扩展其他人的代码,而不必将扩展名插入其命名空间(对于Win32和一般今天存在的大多数代码是GLOBAL NS-首先是创建 namespace 的全部要点:避免全局NS拥挤/污染/歧义/编程意外。
所以,我回到那里是否有更好的方法:扩展现有的代码库,同时不使用扩展名污染它们的NS,但仍然允许直观和有用的名称解析,就像我的代码在它们的内部一样。 NS,但是由我的代码的客户端明确引入的(即,我不想随意插入我的代码,而仅在明确请求的情况下)?
另一个想法:如果我具有以下条件,也许满足我上面的要求:
using namespace X {
code here...
}
我可以在任何地方(包括 header 中)放置这样的构造,而不必担心将X拖到客户的代码中,但是我可以自由地编写源代码,就像在源代码中一样。根 namespace 。
最佳答案
我认为这里不必避免限定 namespace 范围的free()
,但应注意,这与“绝对路径”不同。一方面,如果您具有嵌套的 namespace ,则只需引用最里面的一个:
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 ATL,或者如果需要额外的安全性,则可以使用像c_str()
这样的显式成员函数)。这将完全不需要free
,也不需要那里的任何其他自由函数,因为您可以控制包装器类型及其所在的 namespace ,因此可以照常使用ADL。[EDIT#2] 。问题的这一部分:
allow for intuitive and useful name resolution as one would expect if my code were in their NS but explicitly introduced by the client of my code (i.e. I don't want to inject my code willy-nilly, but only upon explicit request)?
您将它放在命名空间中并由客户编写
using namespace ...
来实现就可以了吗?
关于c++ - C++命名空间的困扰,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1902651/