当我更改包含模板类定义的头文件时,我的编译器(VS2015附带的编译器)首先解析实例化类的源文件,然后才解析头文件。这导致二进制文件不正确。
但是,如果我再次更改头文件并进行编译,则解析顺序是正确的(首先是头,后面是源),并且生成的二进制文件可以正常工作。
编译器解析文件的顺序可以在Build输出窗口中看到,我没有启用并行或多处理器编译选项。
我可以100%的成功率重现这一点。我做错了什么,有什么我可以改变的吗?
代码如下。
Class.h
template<class T> class Class {
void foo () {
WriteToFile("A");
}
Usage.cpp
Class* c = new C();
c->foo();
完全构建/重建。文件输出:A。
第1步:
将以下行添加到foo()
:WriteToFile("B");
编译:输出顺序:Usage.cpp,Class.h
文件输出:A
第2步:
将以下行添加到foo()
:WriteToFile("C")
;`
编译:输出顺序:Class.h,Usage.cpp
文件输出:A B C
继续,直到永远,同样的行为。
注意:我只需按F7到&#34; Build&#34;,完全重建后它可以正常工作,但需要很长时间。
答案 0 :(得分:0)
您的源文件(.cpp)仅被编译,并将包含的头文件(.h)中的代码复制到源文件中。 头文件不是独立编译的。
您可以从Build输出窗口复制日志。
答案 1 :(得分:0)
您发布的代码充满了错误,如果这是您正常代码的示例,则可能发生任何事情。
如上所述,你不应该看到h文件编译。如果您这样做,您可能已将其设置为编译为cpp文件或类似的东西。这是你应该看的第一个地方。
在预处理阶段将H文件添加到CPP文件中,生成长源文件,如果选择编译选项以保留它们,则可以读取这些文件。不知道它的顶端是什么。如果查看这些长文件,那么您将看到Class.h正在#include "Class.h"
语句发生时添加到Usage.cpp中。除非你包含旧版本的Class.h,否则很难看出你所描述的内容可能会发生。除非您使用预编译的头文件,并且您的class.h文件是PCH的一部分,并且您使用的是陈旧的PCH文件。
如果你每次都使用重建,而不是构建(F7),我怀疑问题会消失。我怀疑这是因为PCH生成问题所以请检查stdafx.cpp是否设置为重新生成PCH。
答案 2 :(得分:0)
固定。在Visual Studio解决方案资源管理器中右键单击该文件 - &gt;属性 - &gt;物品种类。对于该特定头文件,它被设置为C / C ++编译器。将其更改为C / C ++标题后,它就可以了。
我认为这是因为当我向解决方案添加新文件时,我右键单击过滤器 - &gt;添加新项目。如果选择了Source文件,我没有把它更改为Header文件,我只想命名文件SomeName.h。它似乎有所作为。基于此,.vcxproj将包含一个以<ClInclude>
或<ClCompile>