关于c ++:未命名的命名空间优于静态?

Superiority of unnamed namespace over 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

<罢工>另外,请注意,在命名空间范围(根据标准)中声明对象时,不推荐使用静态关键字。< /打击>


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

假设您使用static关键字或未命名的namespace使某个函数在模块(翻译单元)内部,因为该函数是模块内部使用的,而在模块外部不可访问。(未命名的namespace除了函数外,还具有使数据和类型定义内部化的优势)。

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

但现在您面临一个问题:这些函数不能再是模块的static,因为static实际上不是指模块,而是指源文件(翻译单元)。您必须使它们非static以允许从该模块的其他部分(对象文件)访问它们。但这也意味着它们对模块不再是隐藏的/私有的:具有外部链接,可以从其他模块访问它们,这不是您的初衷。

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

如果可以指定一些namespaceprivate,也就是说,无论其中定义了什么,它都是由它所属的模块内部使用的,那就太好了。但是C++当然没有这样的概念:"模块",只有"翻译单元",它们与源文件紧密绑定。


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.

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