名前のない名前空間はstatic
キーワードよりもどのように優れていますか?
基本的には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-namespace
はstatic
より優れています。
また、名前空間スコープでオブジェクトを宣言する場合、静的キーワードの使用は推奨されないことに注意してください(標準に従って)。
これに関連する興味深い問題があります:
static
キーワードまたは名前のないnamespace
を使用して、モジュール(翻訳単位)の内部にある関数を作成するとします。この関数はモジュールによって内部的に使用され、外部からはアクセスできないためです。 (名前のないnamespace
sには、関数の他に、データと型定義も内部に作成できるという利点があります)。
時間が経つにつれて、モジュールの実装のソースファイルが大きくなります。それを複数の個別のソースファイルに分割すると、コードをより適切に編成し、定義をより迅速に見つけ、独立してコンパイルできるようになります。
しかし、今、あなたは問題に直面しています:static
は実際にはmoduleを参照していないため、これらの関数はモジュールに対してstatic
になりませんsource file(翻訳単位)へ。そのモジュールの他の部分(オブジェクトファイル)からアクセスできるようにするには、それらを非static
にする必要があります。しかしこれはまた、それらがモジュールに対して非表示/プライベートではなくなったことを意味します:外部リンケージを持っているため、他のモジュールからアクセスできます。これは元々の意図でしたnot。
無名namespace
は、特定のソースファイル(翻訳単位)に対しても定義されており、外部からアクセスできないため、この問題も解決しません。
いくつかのnamespace
がprivate
である、つまり、その中に定義されているものはすべて、それが属するモジュールによって内部的に使用されることを指定できると便利です。しかし、C++には「モジュール」などの概念はなく、「翻訳単位」のみがあり、ソースファイルにしっかりとバインドされています。
C++標準では、セクション7.3.1.1名前のない名前空間、段落2を読み取ります。
名前空間のスコープでオブジェクトを宣言する場合、staticキーワードの使用は非推奨です。unnamed-namespaceは優れた代替手段を提供します。
静的は、オブジェクト、関数、および匿名共用体の名前にのみ適用され、型宣言には適用されません。