gre*_*olf 2 c++ port namespaces
我正在移植一些开源代码,以便它可以构建在另一个c ++编译器上.似乎不断出现的困难和主题之一是编译器提供的标准库的实现差异.
例如,我正在编译的源文件之一包括<sys/types.h>.但是,它给了我以下错误:
Error E2316 g:\Borland\BCC593\Include\sys/types.h 45: 'time_t' is not a member of 'std'
Error E2272 g:\Borland\BCC593\Include\sys/types.h 45: Identifier expected
Run Code Online (Sandbox Code Playgroud)
在查看了根本原因之后,我发现项目的主要包含标题之一包括<sys/types.h>在这种模式中:
project_source1.cpp:
#include "../TargetPlatform.h"
#include "project_config.h"
#include <windows.h>
namespace project_namespace {
#include "project_component/all.h"
// more project includes down here
// ...
}
Run Code Online (Sandbox Code Playgroud)
project_component/all.h:
#ifndef INCLUDE_GUARDS
#define INCLUDE_GUARDS
#include <sys/types.h>
#include "project_header1.h"
#include "project_header2.h"
// and other headers etc..
// followed with class definitions and what not.
#endif
Run Code Online (Sandbox Code Playgroud)
除了一个问题之外,这一切都很好,<sys/types.h>对于我正在移植到的编译器实现了类似的东西:
<sys/types.h> 修剪到本质:
namespace std {
typedef long time_t;
typedef short dev_t;
typedef short ino_t;
typedef short mode_t;
typedef short nlink_t;
typedef int uid_t;
typedef int gid_t;
typedef long off_t;
} // std
using std::time_t;
using std::dev_t;
using std::ino_t;
using std::mode_t;
using std::nlink_t;
using std::uid_t;
using std::gid_t;
using std::off_t;
Run Code Online (Sandbox Code Playgroud)
这就是我看到的编译错误的原因.因为项目包含<sys/types.h> 在它自己的命名空间内,所以像time_t,off_t,dev_t等等被放入范围内project_namespace::std::,这显然不是预期的.
处理这个问题的最佳方法是什么?请记住,可能会以类似的方式定义其他标准库头,而不仅仅是sys/types.h.是否存在与此问题相关或半相关的C++习语(或者由于实现方式的原因,甚至可能与之相矛盾)?如果是这样,怎么能和解?
谢谢
这是一个坏主意.不要这样做.将名称空间声明放在每个头文件中.永远不要#include在命名空间的范围内有指令.
永远不是一个强有力的词,并且在极少数情况下您可能想要这样做.如果您正在使用的文件#include也有#include指令,那么您几乎肯定不希望这样做,甚至比他们没有这样做更多.
如果您需要能够轻松地重命名命名空间或使用相同的标头根据上下文在几个不同的命名空间中声明相同的符号,请使用预处理器来更改命名空间名称.这样做非常难看,但比你现在做的要好得多.
作为快速而肮脏的解决方案,您可以做的一件事是#include <sys/types.h>在命名空间声明之前包含的任何其他系统头.这将导致系统头文件中的双包含保护启动并避免在命名空间内声明内容.
| 归档时间: |
|
| 查看次数: |
1110 次 |
| 最近记录: |