標準ライブラリ (またはブースト) がどのように構成されているかを見てください。std
そのほぼすべてが単一の名前空間内にあります。すべてを独自の名前空間に配置しても、得られるものはほとんどありません。
Boost はほとんどのものを 内boost
に置きますが、主要なライブラリは単一のサブ名前空間 ( boost::mpl
、またはboost::filesystem
など) を取得します。aux
また、ライブラリは通常、内部実装の詳細のために単一のサブ名前空間を定義します。
しかし、通常、深いまたはきめの細かい名前空間階層は目にすることはありません。これは、それらを扱うのが面倒であり、メリットがほとんどまたはまったくないためです。
ここにいくつかの良い経験則があります:
特定のクラスに関連するヘルパー関数は、ADL が機能するように、クラスと同じ名前空間にある必要があります。次に、ヘルパー関数を呼び出すときにその名前を修飾する必要はまったくありません。(で定義されたイテレータsort
の代わりに呼び出す方法と同様)。std::sort
std
それ以外については、名前空間の目的は名前の衝突を避けることであり、それ以外のことではないことを覚えておいてください。そのため、ユーザー コードとの衝突を避けるために、すべてのライブラリを名前空間に配置する必要がありますが、その名前空間内では、衝突する名前を導入する予定がない限り、さらなるサブ名前空間は技術的に必要ありません。
Boost のaux
.
ただし、一般的には、ネストされた名前空間をできるだけ少なくすることをお勧めします。
そして最後に、私は自分の名前空間に短く、入力しやすく、読みやすい名前を使用することを強調する傾向があります (繰り返しますstd
が、従うべき良い例です。短くて要点があり、ほとんどの場合、それ以上ネストされていませんそのため、頻繁に記述する必要がなく、ソース コードが乱雑になりすぎません。)
ヘルパー関数と ADL に関する最初のルールだけで、例を次のように書き直すことができます。
MyLibrary::MyContainer<int> Numbers = Insert(OtherContainer, 123, 456);
次に、次MyLibrary
のように名前を変更できLib
ます。
Lib::MyContainer<int> Numbers = Insert(OtherContainer, 123, 456);
そして、あなたはかなり扱いやすいものになっています。
異なるクラスの同様のユーティリティ関数間で衝突があってはなりません。C++ では、関数をオーバーロードし、テンプレートを特殊化できるため、 と の両方をInsert(ContainerA)
同じInsert(ContainerB)
名前空間に持つことができます。
もちろん、名前空間とクラスの間の衝突は、実際に追加のネストされた名前空間がある場合にのみ可能です。
Library
名前空間内で、どの名前を導入するかを決めるのはあなただけであることを思い出してください。したがって、衝突する名前を作成しないだけで、名前の衝突を回避できます。ユーザー コードとライブラリ コードを分離する名前空間は重要です。これは、この 2 つが互いを認識していない可能性があり、意図しない衝突が発生する可能性があるためです。
ただし、ライブラリ内では、衝突しない名前をすべて付けることができます。