Visual Studio 2010,Intellisense和PCH:除了丑陋的stdafx.h之外,还有什么替代方案?

18
我最近切换到Visual Studio 2010,为了让Intellisense在使用boost库时不要花费半分钟时间才能显示出来,Microsoft建议似乎是使用预编译头文件。
但我以前从未使用过它们(除非被丑陋的ATL向导(TM)强制要求),所以我搜索了一下以弄清它们的工作原理。
基本上,集中式的stdafx.h方法似乎是错误的。我永远不想在所有源文件中包含(即使是便宜的)大量头文件。由于我不使用Windows库(我创建C++/CLI高级包装器,然后使用.NET与外界通信),我没有"一整车不变的巨大头文件"。只有boost和标准库头文件分散在各处。 这个问题有一个有趣的解决方法,但我无法弄清楚如何使其工作。似乎每个源文件都必须编译两次(如果我错了,请纠正我):一次用/Yc和一次用/Yu。这会给开发人员增加负担,必须手动调整构建系统。
我希望找到一些"自动生成每个源文件的一个预编译头文件"的技巧,或者至少是一些"最佳实践",但大多数人似乎都喜欢将全局头文件包含在stdafx.h中。 对我来说有哪些选项可以在每个源文件上使用预编译头文件?我并不真的关心构建时间(只要它们不飙升),我只想让Intellisense工作得一点。

2
那真是个好问题。我通常会放弃使用PCH,转而使用带有ccache的mingw-gcc。这样总是更快的。 - sehe
9
C++ 的 IntelliSense 很糟糕;在 VS2010 中,它比以前稍微好一点。至于预编译头文件,与其费力地去对抗系统,还不如随遇而安。 - Luke
3
只是一个问题:你的问题基本上似乎是在VS2010中Intellisense对Boost支持较慢?Visual Assist X可能是你的一个选择吗? - Bart
VC++ 6.0(微软最后一个好的C++ IDE)曾经有一个“自动使用PCHs”项目选项,它不需要stdafx.h这个东西。现在还有吗?可能没有了... - user2100815
@unapersson:它已被删除,因为它导致了头文件的过多系统重新编译。 - Alexandre C.
显示剩余6条评论
4个回答

9
首先,您对这篇文章的理解是错误的。并不是每个文件都被编译两次。在任何其他文件被编译之前,文件stdafx.cpp会使用/Yc(c表示创建)编译一次,然后您项目中的每个其他文件都会使用/Yu(u表示使用)编译一次,并导入先前从stdafx.cpp保存的状态的结果。
其次,这篇文章已经有7年的历史了,并且是关于VC++ 6的,所以您应该开始怀疑它。但是即使假设其中的信息仍适用于VC++ 2008或2010,它似乎也是错误的建议。它推荐使用/pragma hdrstop的方法是一个无谓的解决方案。如果您的头文件包含您不想在每个文件中都出现的内容,那么它们就不应该放在预编译头文件中。

如果我正确理解了你的最后一句话,那么我根本不应该使用预编译头文件。 - Alexandre C.
1
你不应该为创建符号可能在任何地方都会有危险的头文件使用预编译头文件。相反,它们适用于安全且自包含的头文件,例如boost和stl,或者实际上需要在任何地方包含的东西,例如windows.h。 - Alan

5

你的问题基本上是在VS2010中使用Boost时Intellisense很慢?我没有直接解决此问题的方法,但Visual Assist X可能是一个选项。我现在已经在各种版本的Visual Studio中使用它,感觉非常好。虽然不是直接的解决方案,但它可能适用于你。


值得注意的是,Visual Assist对于boost的自动完成不会有显著的改进,因为boost是一个相当复杂的库,而自动完成工具似乎不能很好地与之配合。然而,Visual Assist是一款非常棒的工具,我无法想象没有它该如何工作,所以你应该去试试。除此之外,我似乎无法理解Intellisense和预编译头之间的联系,难道VS从预编译头中获取Intellisense吗? - Grim
我接受这个答案,因为它回答了问题(关于Intellisense,标题已经编辑)。我更喜欢解决问题的答案(尽管不是免费的),而不是描述一个15年前的烦人功能的好答案。谢谢大家。 - Alexandre C.

4

如果正确使用,预编译头并不太糟糕。

不要将它们用作适当和精确 #includes 的替代品,而是将其作为加速的一种方式。通过使预编译头在发布版本中不执行任何操作,只在调试中加速处理来实现这一点。


1
这似乎是合理的。这也意味着除非您的源文件中有很多巨大的标题(这是我努力避免的),否则不应使用它们。 - Alexandre C.

3
你错了,每个文件只编译一次。你有一个.cpp文件,它使用/Yc编译,其余文件使用/Yu编译。默认情况下,使用/Yc的文件是stdafx.cpp,其中包含一行代码:#include "myMainHeader.h"(将名称从默认值更改)。所有其他.cpp文件必须以#include "myMainHeader.h"开头。当编译/Yc文件时,编译器的整个内部状态被保存。当编译每个其他文件时,该文件被加载。这就是为什么必须从包含PCH开始,以便/Yu选项不会改变编译结果,而只会改变时间。Xcode并不要求这样做,并且会在.cpp文件以正确的include指令开头时使用PCH。我曾经使用过依赖于此的库,如果没有PCH就无法构建。

1
@Alexandre,这篇文章讨论了在每个文件中使用/FI选项或#pragma hdrstop而不是使用#include指令。出于兼容性的考虑,我不建议这样做。 - IronMensan
好的,抱歉有点严厉,但我似乎没有理解实际上需要一个额外的文件来生成PCH。现在我明白了,那个人的解决方案对我的目的来说似乎很糟糕:它旨在在构建发布产品时激活,在调试时停用。 - Alexandre C.

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接