是否可以检测在给定的代码点您是否在命名空间中?特别是,如果文件包含在全局命名空间中,我想包含一个警告。
问问题
1820 次
3 回答
2
好的做法是在全局命名空间中包含所有标头。在文件开头打开所有需要的命名空间并在结束前关闭它们。另一种方式将不可避免地导致一堆问题。
**评论扩展**
为防止意外包含,您可以执行以下操作:
In header:
#ifndef INTERNAL_INCLUDE
#error ...
#endif
When used:
#define INTERNAL_INCLUDE
#include "internal.h"
#undef INTERNAL_INCLUDE
于 2012-09-13T16:00:00.767 回答
2
如果标头未包含在全局命名空间中,我可以给你一个提示,它会生成编译错误。如果我知道 C++ 构造肯定会生成编译器警告(除了#warning),那么它可以用来代替编译错误。
放入您的标题:
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
无论如何-没有人敢将您的标头包含在全局以外的名称空间中。
于 2012-09-13T18:02:01.377 回答
1
您可以这样做,但需要第二个标头,在第一个标头之前包含在全局命名空间中,这带来了一些不便。
// 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
,或者滚动你自己的.
于 2012-09-13T16:38:38.593 回答