根据标准委员会的说法,为什么匿名命名空间不能代替命名空间静态?
根据这个答案 ,命名空间范围的静态variables在C ++ 11中是不赞成的。 也就是说,它们在C ++ 03中被弃用,因为匿名的命名空间被认为是更好的。 但是C ++ 11不推荐使用它们。
为什么? N3296列举了这个推理 :
命名空间范围内的静态使用不应该被弃用。 匿名命名空间不足以取代function。
这显然是委员会接受的。 为什么? 什么是匿名命名空间不完全取代这个function?
我更喜欢有一些文件或标准委员会讨论文件的答案。
这是一个更深入的解释。
虽然7.3.1.1 [namespace.unnamed]指出,在命名空间范围内使用static关键字来声明variables已被废弃,因为未命名的命名空间提供了一个优越的替代scheme,在可预见的将来,这个function不太可能被删除特别是考虑到C兼容性问题。 委员会应考虑取消弃用。
我知道的一个问题是,匿名命名空间不能专门化命名空间块之外的模板。 这就是为什么引入inline namespace
原因,尽pipestatic
也是如此。 另外, static
macros与macros很好。
使用未命名的命名空间,您不能在当前所在的同一名称空间内提供可变的内部链接。使用static
,您可以。 例如,以下使用未命名的名称空间不会给出全局variables的内部链接
namespace { int a; } int a; // oops, no error!
如果第a
被声明为static
,那么在全局范围声明第二个a
的尝试将立即出现错误,因为第一个a
已经存在于全局范围内。
因此,为了实现他们的身份唯一的工作,未命名的名称空间将实体放置到不同的名称空间(除了影响它们的链接之外)。 static
只影响链接,而不改变哪些函数和variables的成员空间。
壕沟中的用户应该是名称空间中的名称(匿名名称空间的标准术语)具有外部链接,并且在名称空间级别声明为static
的名称具有内部链接。
内部链接有两个好处,其中只有一个没有名字的命名空间:
-
他们使翻译单位的本地名称。 我可以用不同的翻译单位不同地定义相同的function
fun
,而不违反单一定义规则。 该属性由未命名名称空间中的名称共享,方法是使用唯一的名称空间名称对其进行装饰。 -
它们阻止名称进入全局符号表。 这是严格的优化,但在实践中是一个重要的。 该属性不被未命名的命名空间中的名称共享。
因此,一般来说,使用static
的程序为其翻译单元本地命名空间级别的函数生成较less的链接器的工作,并可能执行比使用未命名的命名空间等效的程序更快。
也就是说,您需要使用未命名的名称空间作为要作为模板parameter passing的types,因为模板参数必须具有外部链接。
所以我通常做下面的事情:将free函数定义为static
函数,但是将types放入未命名的名称空间中。