在将项目从Visual Studio 2005移植到2013时,我遇到了这种奇怪的行为,我无法找到解释。上下文是关于通过多次包含某个头文件来创建模板特化,但是在每个包含之前更改预处理器定义以基本上生成不同的类声明。
我可以将问题缩小到以下情况:
gen.hpp
#ifdef ENABLE_GEN
#ifdef GEN_SWAP_ORDER // (1)
class Foo {};
#else
class Bar {};
#endif
#endif
的main.cpp
#define ENABLE_GEN
#include "gen.hpp"
#define GEN_SWAP_ORDER
#include "gen.hpp"
int main()
{
Foo foo;
Bar bar;
}
这符合预期,即Foo
和Bar
都在main()
中声明并可用。
现在,要导致此问题,请将标记为(1)的行中的#ifdef
更改为#ifndef
,这应该只会导致Foo
和{{1}的顺序宣布要交换。但相反,编译失败了:
Bar
预处理文件看起来像这样(剥离了一些空格):
1>c:\path\to\main.cpp(10): error C2065: 'Bar' : undeclared identifier
1>c:\path\to\main.cpp(10): error C2146: syntax error : missing ';' before identifier 'bar'
1>c:\path\to\main.cpp(10): error C2065: 'bar' : undeclared identifier
我的问题是:我错过了什么吗?出于某种原因这是预期的行为吗?这是一个编译器设置/错误,使得Visual Studio在认为它有头文件保护时(由于#line 1 "c:\\path\\to\\main.cpp"
#line 1 "c:\\path\\to\\gen.hpp"
class Foo {};
#line 8 "c:\\path\\to\\gen.hpp"
#line 10 "c:\\path\\to\\gen.hpp"
#line 4 "c:\\path\\to\\main.cpp"
int main()
{
Foo foo;
Bar bar;
}
)第二次跳过标题内容(包括#else
部分)?
谢谢!