Superiority of unnamed namespace over static?
未命名的名称空间如何优于static关键字?
- 但是,根据标准委员会的说法,未命名的名称空间并不能完全替代静态名称空间。还有一些实例未命名的名称空间失败,只有static起作用。
您基本上引用的是C++标准的7.3.1.1/2节。
<罢工>
The use of the static keyword is
deprecated when declaring objects in a
namespace scope; the
unnamed-namespace provides a superior
alternative.
未命名的命名空间优于静态关键字,主要是因为关键字static仅适用于变量声明和函数,而不适用于用户定义的类型。
下面的代码在C++中是有效的
1 2 3
| //legal code
static int sample_function() { /* function body */ }
static int sample_variable; |
但此代码无效:
1 2 3
| //illegal code
static class sample_class { /* class body */ };
static struct sample_struct { /* struct body */ }; |
所以解决方案是,未命名的名称空间,即,
1 2 3 4 5 6
| //legal code
namespace
{
class sample_class { /* class body */ };
struct sample_struct { /* struct body */ };
} |
希望它能解释为什么unnamed-namespace优于static。
<罢工>另外,请注意,在命名空间范围(根据标准)中声明对象时,不推荐使用静态关键字。< /打击>
- 更一般地说,未命名的命名空间允许外部链接。这就是本地到翻译单元类声明的原因。它还允许将外部链接字符串常量用作模板参数。
- @阿尔夫:没错。感谢您的加入。-)
- 正如Fred Nurk在另一个答案中所指出的,这似乎是从最新的C++0X FCD(N32 25)中删除的EDOCX1 0的注释。
- "请注意,在命名空间范围(根据标准)中声明对象时,不推荐使用静态关键字。"您认为这种拒绝有任何影响吗?我的意思是。
- @好奇的家伙:正如我在同一行中写的,你可能忽略了这句话:"…按照标准"。
- @纳瓦兹,我认为这是"不"。
- @好奇心的家伙:连标准都不这么认为了。C++ 11已经删除了它的蔑视!
- 纳瓦兹认为,有一天,EDCOX1(1)的一些历史意义将从C++中删除,确实是有趣的(5分钟)。
- 你在回答你自己的问题,并对自己说谢谢。-o
- 仅仅在cpp中定义类(没有匿名名称空间,没有静态名称空间)有什么区别?
- @Luchiangrigore在案例2中连接故障.cpp定义了一个同名的类。
- 请编辑答案以解释神秘的删除…
- @在另一个问题中解释了删除。
与此相关的一个有趣的问题是:
假设您使用static关键字或未命名的namespace使某个函数在模块(翻译单元)内部,因为该函数是模块内部使用的,而在模块外部不可访问。(未命名的namespace除了函数外,还具有使数据和类型定义内部化的优势)。
随着时间的推移,模块实现的源文件会变大,您希望将其拆分为几个单独的源文件,这样可以更好地组织代码、更快地找到定义并独立编译。
但现在您面临一个问题:这些函数不能再是模块的static,因为static实际上不是指模块,而是指源文件(翻译单元)。您必须使它们非static以允许从该模块的其他部分(对象文件)访问它们。但这也意味着它们对模块不再是隐藏的/私有的:具有外部链接,可以从其他模块访问它们,这不是您的初衷。
未命名的namespace也不能解决这个问题,因为它也是为特定的源文件(翻译单元)定义的,不能从外部访问。
如果可以指定一些namespace是private,也就是说,无论其中定义了什么,它都是由它所属的模块内部使用的,那就太好了。但是C++当然没有这样的概念:"模块",只有"翻译单元",它们与源文件紧密绑定。
- 无论如何,这将是一个黑客和一个有限的解决方案,但是您可以将带有内部静态或名称空间函数的cpp文件包含到您的"主"cpp文件中。然后从构建中排除这些"附属"cpp文件,您就完成了。唯一的问题是,如果您有两个或多个"主"cpp文件,并且它们都想使用其中一个"附属"cpp文件中的酷函数…
- 解决方案不是将继承与私有/受保护/公共的静态函数一起使用吗?
- C++ 20介绍了模块,解决了你的问题。
C++标准在7.3.1.1节未命名的命名空间中阅读,第2段:
The use of the static keyword is
deprecated when declaring objects in a
namespace scope, the unnamed-namespace
provides a superior alternative.
静态只适用于对象、函数和匿名联合的名称,而不适用于类型声明。
- 不,没有。有草稿。很快,另一份草案又恢复了这种愚蠢的变化。