简体   繁体   English

在C ++中检测名称空间

[英]Detecting namespace in c++

Is it possible to detect whether at a given point of code you are in a namespace? 是否可以检测在给定的代码点您是否在名称空间中? In particular, I want to include a warning if a file is being including in the global namespace. 特别是,如果文件要包含在全局名称空间中,则要添加警告。

Good practice is including all headers in global namespace. 好的做法是在全局名称空间中包括所有标头。 Open all needed namespaces at the beginning of file and close them before end. 在文件的开头打开所有需要的名称空间,并在结束之前将其关闭。 Another way will inevitably lead to heap of problems. 另一种方法将不可避免地导致大量问题。

** Comment extension ** ** 评论扩展 **

To prevent unintended inclusion, you can do something like this: 为防止意外收录,您可以执行以下操作:

In header:
#ifndef INTERNAL_INCLUDE
#error ...
#endif

When used:
#define INTERNAL_INCLUDE
#include "internal.h"
#undef INTERNAL_INCLUDE

I can give you a hint that generates compilation error if header is not include in global namespace. 我可以给您一个提示,如果标头未包含在全局名称空间中,则会生成编译错误。 If I know C++ constructiom which for sure generates compiler warning (other that #warning) then it could be used instead of compilation error. 如果我知道C ++构造函数肯定会生成编译器警告(除了#warning),则可以使用它代替编译错误。

Put in your header: 放入标题:

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];
};

When your header is include in some namespace you'll get an error. 当标题包含在某些命名空间中时,您将得到一个错误。

Like in this example: 像这个例子:

namespace Some {

struct TestGlobalNamespace
{
   int test_namespace[AreSame<TestGlobalNamespace, ::TestGlobalNamespace>::VALUE];
};

}

You'll get: 你会得到:

prog.cpp:17: error: size of array ‘test_namespace’ is negative

[UPDATE] [更新]

However the more probably would be this kind of errors: 但是,更可能是这种错误:

prog.cpp:17: error: ‘::TestGlobalNamespace’ has not been declared
prog.cpp:17: error: template argument 2 is invalid

Anyway - no one will dare to include your header to namespace other than global. 无论如何-除了全局名称,没有人敢将您的标头包含在名称空间中。

You can do this with the small inconvenience of requiring a second header, to be included in the global namespace before the first. 您可以在需要第二个标头的情况下带来一点不便,只需将第二个标头包含在全局名称空间中即可。

// 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

This will give reasonably friendly error messages if you break either of these two rules, and a somewhat less friendly error if you include stuff_guard.h from a non-global namespace. 如果您违反这两个规则中的任何一个,这将给出合理的友好错误消息,而如果您从非全局名称空间中包含stuff_guard.h ,则将给出不太友好的错误stuff_guard.h

If you're stuck with an old compiler and static_assert isn't available, then you could use BOOST_STATIC_ASSERT , or roll your own . 如果您使用的是旧的编译器,并且无法使用static_assert ,则可以使用BOOST_STATIC_ASSERT ,也可以自己滚动

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM