web-dev-qa-db-ja.com

名前のない名前空間の静的に対する優位性?

名前のない名前空間はstaticキーワードよりもどのように優れていますか?

112
Nawaz

基本的にはC++標準のセクション$ 7.3.1.1/2を参照していますが、

名前空間のスコープでオブジェクトを宣言する場合、staticキーワードの使用は推奨されません。名前のない名前空間は、優れた代替手段を提供します。

名前のない名前空間は、主にキーワードstaticがユーザー定義のtypesではなく、変数宣言と関数にのみ適用されるため、静的キーワードよりも優れています。

次のコードは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-namespacestaticより優れています。

また、名前空間スコープでオブジェクトを宣言する場合、静的キーワードの使用は推奨されないことに注意してください(標準に従って)。

116
Nawaz

これに関連する興味深い問題があります:

staticキーワードまたは名前のないnamespaceを使用して、モジュール(翻訳単位)の内部にある関数を作成するとします。この関数はモジュールによって内部的に使用され、外部からはアクセスできないためです。 (名前のないnamespacesには、関数の他に、データと型定義も内部に作成できるという利点があります)。

時間が経つにつれて、モジュールの実装のソースファイルが大きくなります。それを複数の個別のソースファイルに分割すると、コードをより適切に編成し、定義をより迅速に見つけ、独立してコンパイルできるようになります。

しかし、今、あなたは問題に直面しています:staticは実際にはmoduleを参照していないため、これらの関数はモジュールに対してstaticになりませんsource file(翻訳単位)へ。そのモジュールの他の部分(オブジェクトファイル)からアクセスできるようにするには、それらを非staticにする必要があります。しかしこれはまた、それらがモジュールに対して非表示/プライベートではなくなったことを意味します:外部リンケージを持っているため、他のモジュールからアクセスできます。これは元々の意図でしたnot

無名namespaceは、特定のソースファイル(翻訳単位)に対しても定義されており、外部からアクセスできないため、この問題も解決しません。

いくつかのnamespaceprivateである、つまり、その中に定義されているものはすべて、それが属するモジュールによって内部的に使用されることを指定できると便利です。しかし、C++には「モジュール」などの概念はなく、「翻訳単位」のみがあり、ソースファイルにしっかりとバインドされています。

6
SasQ

C++標準では、セクション7.3.1.1名前のない名前空間、段落2を読み取ります。

名前空間のスコープでオブジェクトを宣言する場合、staticキーワードの使用は非推奨です。unnamed-namespaceは優れた代替手段を提供します。

静的は、オブジェクト、関数、および匿名共用体の名前にのみ適用され、型宣言には適用されません。

6
Salgar