你能用#define来改变#include吗?

时间:2014-07-08 14:54:54

标签: c++ include c-preprocessor

是否可以在预先处理期间将使用#include <foo>#include "foo"的库更改为不同的库,以便它可以作为不同的库,例如#include <bar>?我有一个库只在一个上下文中不使用当前的#include语句,但在其他地方工作正常,所以我不想直接更改它。是否可以使用#define来解决此问题?

2 个答案:

答案 0 :(得分:8)

有两种方法可以做到这一点。更简单,更明显的方式:

#define INCLUDE_FOO

// ...

#ifdef INCLUDE_FOO
#include <foo>
#else
#include <bar>
#endif

更短但更精彩的方式:

#define FOO_HEADER "foo"

// ...

#include FOO_HEADER

如果您使用第二种方式,则必须小心,因为C标准没有完全定义#include的行为,后跟任何不是"..."<...>的行为。它说&#34;任何不是......&#34;完全宏扩展,应用#include行的特殊标记化规则(例如<foo.h>是五个令牌,而不是一个) 然后发生一些实现定义。

如果完整宏扩展的结果是单个字符串文字标记,那么我所知道的所有实现都会按预期执行,即他们会将其视为已写入#include "...",{{1} }是字符串文字的内容。 (但是,字符串文字中反斜杠的行为可能与您期望的不同。仅对目录分隔符使用正斜杠;这在Windows和其他地方都可靠地工作。)

如果完全宏扩展的结果是其他任何,则行为是不可预测的,并且不仅在实现之间,而且在相同实现的点发行版之间也不同。避免。

附录:如果...行以两种典型格式之一开头写作......

#include

...然后宏观扩张不会发生,也不会被迫发生。这意味着你可能希望避免因问题而改变第三方标题。

答案 1 :(得分:3)

基本上在您的cpp文件中,您可以定义一个切换包含文件行为的变量:

所以在a.cpp中

#define BAR
#include "myHeader.h"

在&#34; myheader.h中:&#34;

#ifdef BAR
#include <bar>
#else
#include <foo>
#endif

关于您可以使用预处理器宏来切换行为的其他方法,有一篇很好的GOTW文章