コードの特定のポイントで名前空間にいるかどうかを検出することは可能ですか?特に、ファイルがグローバル名前空間に含まれている場合の警告を含めたいと思います。
3 に答える
グローバル名前空間にすべてのヘッダーを含めることをお勧めします。ファイルの先頭で必要なすべての名前空間を開き、終了する前にそれらを閉じます。別の方法は必然的に問題の山につながります。
**コメント拡張**
意図しない包含を防ぐために、次のようなことを行うことができます。
In header:
#ifndef INTERNAL_INCLUDE
#error ...
#endif
When used:
#define INTERNAL_INCLUDE
#include "internal.h"
#undef INTERNAL_INCLUDE
ヘッダーがグローバル名前空間に含まれていない場合にコンパイルエラーを生成するヒントを提供できます。確かにコンパイラ警告(#warning以外)を生成するC ++構文を知っている場合は、コンパイルエラーの代わりに使用できます。
ヘッダーを入れてください:
template <class A, class B>
struct AreSame { enum { VALUE = -1 }; };
template <class A>
struct AreSame<A,A> { enum { VALUE = 1 }; };
struct TestGlobalNamespace
{
int test_namespace[AreSame<TestGlobalNamespace, ::TestGlobalNamespace>::VALUE];
};
ヘッダーが名前空間に含まれていると、エラーが発生します。
この例のように:
namespace Some {
struct TestGlobalNamespace
{
int test_namespace[AreSame<TestGlobalNamespace, ::TestGlobalNamespace>::VALUE];
};
}
あなたが得るでしょう:
prog.cpp:17: error: size of array ‘test_namespace’ is negative
[アップデート]
ただし、この種のエラーが発生する可能性が高くなります。
prog.cpp:17: error: ‘::TestGlobalNamespace’ has not been declared
prog.cpp:17: error: template argument 2 is invalid
とにかく-グローバル以外の名前空間にヘッダーを含めることをあえてする人はいないでしょう。
これを行うには、最初のヘッダーの前にグローバル名前空間に含める2番目のヘッダーが必要になるという小さな不便があります。
// stuff_guard.h - include from global namespace to guard stuff.h
#ifndef STUFF_GUARD_H
#define STUFF_GUARD_H
typedef char stuff_guard[1];
#endif
// stuff.h - must be included from non-global namespace, after stuff_guard.h
// No include guard - may be included multiple times, in different namespaces.
#ifndef STUFF_GUARD_H
#error stuff_guard.h must be included before stuff.h
#endif
typedef char stuff_guard[2];
static_assert(sizeof (stuff_guard) != sizeof (::stuff_guard),
"stuff.h must not be included from the global namespace");
// Put your stuff here
これにより、これら2つのルールのいずれかに違反した場合はかなりわかりやすいエラーメッセージが表示さstuff_guard.h
れ、非グローバル名前空間からインクルードした場合は多少わかりにくいエラーメッセージが表示されます。
古いコンパイラで立ち往生していてstatic_assert
利用できない場合は、を使用するBOOST_STATIC_ASSERT
か、独自のコンパイラをロールすることができます。