在代码的某个给定点,是否可能检测出您所处的命名空间?特别是,如果一个文件被包含在全局命名空间中,我想发出警告。
在代码的某个给定点,是否可能检测出您所处的命名空间?特别是,如果一个文件被包含在全局命名空间中,我想发出警告。
良好的实践是将所有标题包含在全局命名空间中。在文件开头打开所有需要的命名空间,在结尾之前关闭它们。其他方式不可避免地会导致一系列问题。
** 注释扩展 **
为了防止意外的包含,您可以采取以下措施:
In header:
#ifndef INTERNAL_INCLUDE
#error ...
#endif
When used:
#define INTERNAL_INCLUDE
#include "internal.h"
#undef INTERNAL_INCLUDE
#ifndef _SOME_VAR_ #error bad include #endif
。 - Pavel Ognev我可以给你一个提示,如果头文件没有包含在全局命名空间中,则会生成编译错误。如果我知道确定会生成编译器警告(不是 #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
static_assert(AreSame<TestGlobalNamespace, ::TestGlobalNamespace>::VALUE
== 1);` 吗? - PiotrNycz您可以通过需要在第一个头文件之前包含在全局命名空间中的第二个头文件来实现此操作,虽然会稍微有些不便。
// 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
如果您违反这两个规则中的任何一个,它将提供相当友好的错误消息;如果您从非全局命名空间包含stuff_guard.h
,则会提供一条略微不太友好的错误消息。
如果您使用旧编译器且无法使用static_assert
,则可以使用BOOST_STATIC_ASSERT
或自己编写。