未命名名称空间优于静态名称空间?


Answers:


133

您基本上是指C ++ 03标准的§7.3.1.1/ 2部分,

在命名空间范围内声明对象时,不建议使用static关键字。无名命名空间提供了一种更好的选择。

请注意,本段已在C ++ 11中删除。不再推荐使用每个static功能!

尽管如此,未命名的名称空间优于static关键字,主要是因为该关键字static仅适用于变量声明和函数,不适用于用户定义的类型

以下代码在C ++中有效

   //legal code
   static int sample_function() { /* function body */ }
   static int sample_variable;

但是此代码无效:

   //illegal code
   static class sample_class { /* class body */ };
   static struct sample_struct { /* struct body */ };

所以解决方案是,无名空间

   //legal code
   namespace 
   {  
        class sample_class { /* class body */ };
        struct sample_struct { /* struct body */ };
   }

希望它能解释为什么unnamed-namespace优于static

另外,请注意,在命名空间范围内声明对象时(根据标准),不建议使用static关键字。


11
更一般而言,未命名的名称空间允许外部链接。这就是启用本地到翻译单元类声明的原因。它还允许例如外部链接字符串常量用作模板参数。
干杯和健康。-Alf 2010年

10
正如弗雷德·纽克(Fred Nurk)在您的另一个回答中所指出的,此deprecated评论似乎已从最新的C ++ 0x FCD(n3225)中删除。
Matthieu M.

36
您正在回答自己的问题,并对自己说声谢谢:-o
manpreet singh 2013年

11
与仅在cpp中定义类(无匿名名称空间,无静态)有什么区别?
Luchian Grigore

6
@LuchianGrigore情况2的链接麻烦.cpp是定义了一个具有相同名称的类。
Xaqq 2014年

8

有一个有趣的问题与此相关:

假设您使用static关键字或未命名namespace在模块(转换单元)内部建立某些功能,因为该功能旨在由模块内部使用,而不能在模块外部访问。(namespace除了函数之外,未命名s的优点还在于使数据和类型定义成为内部的)。

随着时间的流逝,模块实现的源文件会越来越大,您希望将其拆分为几个单独的源文件,这样可以更好地组织代码,更快地找到定义,并独立进行编译。

但是现在您遇到了一个问题:这些功能不再是static模块的,因为static它实际上不是引用模块,而是引用源文件(翻译单元)。您不得不将它们设置为非static允许它们从该模块的其他部分(目标文件)进行访问。但这也意味着它们不再对模块隐藏/专用:具有外部链接,可以从其他模块访问它们,这并不是您的初衷。

未命名namespace也不会解决此问题,因为它也是为特定的源文件(翻译单元)定义的,因此无法从外部访问。

最好指定一个namespaceis private,也就是说,无论其中定义什么,都应由其所属的模块在内部使用。但是,当然,C ++没有“模块”这样的概念,只有“翻译单元”,它们紧密地绑定到源文件。


3
无论如何,这将是一个hack和有限的解决方案,但是您可以将带有内部静态或命名空间功能的cpp文件包含到“主要” cpp文件中。然后从构建中排除这些“卫星” cpp文件,即可完成。唯一的问题是,如果您有两个或多个“主要” cpp文件,并且它们都想使用其中一个“卫星” cpp文件中的酷功能...
Sergey 2014年

解决方案不是在私有/受保护/公共与静态函数中使用继承吗?
阿里(Ali)

C ++ 20引入了模块,可以解决您的问题。
LF

4

C ++标准的内容在第7.3.1.1节“未命名的名称空间”的第2段中:

在命名空间范围内声明对象时,不建议使用static关键字,unnamed-namespace提供了一种更好的选择。

静态仅适用于对象,函数和匿名联合的名称,不适用于类型声明。


5
不,不是。起草了。此后不久,另一份草案又恢复了这一愚蠢的改变。
underscore_d
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.