有什么办法可以在所有新的 Qt 项目上强制 QT_NO_FOREACH 吗?

Is there any way to force QT_NO_FOREACH on all new Qt projects?

自从在 C++11 中包含 range-for 之后,我们一直在迁移我们的 Qt 代码,因此它不再使用 Q_FOREACH/foreach 宏。为了强制迁移,我们手动将 QT_NO_FOREACH 预处理器定义添加到我们检查的每个项目中。我们使用 Visual Studio 和 Qt VS Tools 插件。

我的问题是:有什么方法可以自动将这样的宏添加到新的Qt 项目中吗?我已经检查了全局 Qt VS 工具设置,但那里什么也没有。我们可以更改加载项中的某些隐藏变量吗?

显然,我们可以手动添加它们,但我们更希望有一些一次性解决方案。我们还考虑了 属性 页面的使用,但它们要么是基于每个用户的(不是存储库的一部分,并且将适用于所有项目,而不仅仅是 Qt 的),要么必须手动包含在项目中(在这种情况下,在项目设置中手动添加定义会更容易。


注意:我们知道将 Q_FOREACH 形式迁移到 range-for 的含义,以及如何正确进行更改以避免 COW 惩罚。如果您想了解更多信息,请查看 here, here and here.

查看Qt VS Tools的源代码可以看出,预处理器定义是从位于<QTDIR>\mkspecs\win32-msvcqmake.conf文件的内容中添加的,其中包括<QTDIR>\mkspecs\common\msvc-desktop.conf.

只需将 QT_NO_FOREACH 定义添加到这些文件中的任何一个,所有使用该版本 Qt 的新项目现在都将删除对 Q_FOREACH 的支持。我更喜欢将它添加到 common\msvc-desktop.conf,因为它被所有 VS 项目使用。

DEFINES += QT_NO_FOREACH

注意:添加define后请使用新的VS实例,因为插件会缓存qmake.conf文件的内容。


如果好奇,Qt VS 工具中添加这些定义的确切位置是在 WriteProjectBasicConfigurations(uint type, bool usePrecompiledHeader, VersionInformation vi) 方法中,文件 <qt-vstools>\src\qtprojectlib\QtProject.cs:

// add some common defines
compiler.SetPreprocessorDefinitions(vi.GetQMakeConfEntry("DEFINES").Replace(" ", ","));

我对这个问题的第一个想法是修改 Qt 的模板,但它有两个缺点:模板会随着插件的每个新版本而更新,更重要的是,正如您在上面看到的代码,任何预处理器定义在项目的初始配置期间都会被覆盖。