今日、誰かがヘッダー ファイルで匿名の名前空間を使用してはならないことを SO で主張しました。通常はこれで問題ありませんが、標準ライブラリの 1 つがヘッダー ファイルで匿名の名前空間を使用して何らかの初期化を実行していると誰かに言われたことを覚えているようです。
私は正しく覚えていますか?誰か詳細を記入できますか?
今日、誰かがヘッダー ファイルで匿名の名前空間を使用してはならないことを SO で主張しました。通常はこれで問題ありませんが、標準ライブラリの 1 つがヘッダー ファイルで匿名の名前空間を使用して何らかの初期化を実行していると誰かに言われたことを覚えているようです。
私は正しく覚えていますか?誰か詳細を記入できますか?
ヘッダー内の名前のない名前空間が役立つ唯一の状況は、コードをヘッダーファイルとしてのみ配布する場合です。たとえば、Boostの大規模なスタンドアロンサブセットは純粋にヘッダーです。
ignore
別の回答で言及されているタプルのトークンは1つの例であり_1
、_2
などのバインドプレースホルダーは他のものです。
匿名の名前空間をヘッダー ファイルに入れる意味がわかりません。標準ヘッダーと libstdc++ ヘッダーを grep しましたが、tuple
ヘッダー (C++1x のもの) 以外に匿名の名前空間は見つかりませんでした:
// 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 の要素には左側の変数が割り当てられます (こちらを参照)。この反復子にも同様の手法が使用されます。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
など) である可能性があります。