SO今日、ヘッダーファイルで匿名の名前空間を使用してはならないことを主張しました。通常これは正しいですが、標準ライブラリの1つがヘッダーで匿名の名前空間を使用していると誰かが教えてくれたことを覚えていますある種の初期化を実行するファイル。
私は正しく覚えていますか?誰かが詳細を記入できますか?
ヘッダーの名前のない名前空間が役立つ唯一の状況は、コードをヘッダーファイルのみとして配布する場合です。たとえば、Boostの大規模なスタンドアロンサブセットは純粋なヘッダーです。
別の回答で述べられているタプルのトークンignore
は、1つの例、_1
、_2
など。バインドプレースホルダは他のものです。
ヘッダーファイルに匿名の名前空間を挿入しても意味がありません。私は標準とlibstdc ++ヘッダーをgrepしましたが、Tuple
ヘッダー(C++ 1xのもの)に1つ以外の匿名の名前空間は見つかりませんでした:
// A class (and instance) which can be used in 'tie' when an element
// of a Tuple is not required
struct _Swallow_assign
{
template<class _Tp>
_Swallow_assign&
operator=(const _Tp&)
{ return *this; }
};
// TODO: Put this in some kind of shared file.
namespace
{
_Swallow_assign ignore;
}; // anonymous namespace
これはあなたができるようにするためです
std::tie(a, std::ignore, b) = some_Tuple;
some_Tupleの要素には左側の変数が割り当てられます( here を参照)。同様の手法が this イテレータに使用されます。 2番目の要素は無視されます。
しかし、彼らが言うように、それは.cppファイルに入れられ、1つのインスタンスはすべてのユーザーによって共有されるべきです。彼らはそれを次のようにヘッダーに宣言します:
extern _Swallow_assign ignore;
さまざまな翻訳単位で変数のデフォルト値を提供するために使用されるのを見てきました。ただし、名前が衝突した場合、予期しない動作が発生する可能性があります。
例
a.hpp
namespace
{
const char name[] = "default";
}
// This macro will hide the anonymous variable "name"
#define SET_NAME(newname) \
static const char name[] = newname;
b.cpp
#include "a.hpp"
SET_NAME("file b") // name is "file b" in this translation unit
c.cpp
#include "a.hpp"
SET_NAME("file c") // name is "file c" in this translation unit
d.cpp
#include "a.hpp"
// name is "default" in this translation unit
e.cpp
#include "a.hpp"
static const char name[] = "unintended";
// accidently hiding anonymous name
ヘッダーで匿名の名前空間を使用することによるプラスのメリットは実際にはありません。同じシンボル宣言が原因で発生する混乱は、本質的に、そのヘッダーを含むコンパイルユニットでの別のことは、時期尚早で痛々しいほど脱毛するための保証された方法になることを意味します。
初期化の場合、それはおそらくiostream
sヘッダー(istream
、ios
など)です。