IWYU(包含您使用的内容)通常要求您直接包含导出您正在使用的每个符号的每个标头。这对于您自己的项目标题来说很好,并且实际上是您想要实现的状态。但对于 STL 标头,您不想这样做,因为您很容易遇到依赖于版本或平台特定细节的情况。我在使用
std::string
的 operator[]
时遇到了问题。该运算符需要 struct __alloc_traits
,它恰好在 ext/alloc_traits.h
中声明,因此它告诉我必须包含此标头。但记录在案的获取它的方法是包含 <string>
,我已经在这样做了。我进行了广泛的搜索,看来 IWYU 对此只提供了两种补救措施:
实用程序。但这意味着每次我使用
std::string
s 索引运算符时,我都必须在代码中添加 pragma 注释。
映射。这意味着每次 IWYU 告诉我包含某个标头时,它都应该用另一个标头替换该标头。问题是,
ext/alloc_traits
包含在数十个标头中,其中包括 unordered_map、list 和 tree。映射无法知道我已经包含了哪些。没有记录的方法来创建到空包含列表的映射。
我尝试了以上方法。由于混乱,pragma 不切实际。它总是会成为一个绊脚石,我无法激励我的团队使用 IWYU 来解决这些问题。映射不灵活,最终解决的是不同的问题。我唯一的办法是将 IWYU 包装在另一个脚本中,过滤掉糟糕的建议,但这会带来维护负担。
实际上,我找到了一种没有记录的方法来解决这个问题。您可以指定多个映射,iwyu 足够聪明,可以找出您应该使用哪一个。在本例中,我创建了两个映射:
映射.imp
[
{"include" : [ "<ext/alloc_traits.h>", "private", "<unordered_map>", "public" ]},
{"include" : [ "<ext/alloc_traits.h>", "private", "<string_view>", "public" ]},
]
由于没有记录,我不知道这是否会导致 iwyu 告诉我始终包含 both
<unordered_map>
和 <string>
,但事实证明它足够聪明,可以理解,只要我包含一个其中,我很高兴可以开始,它不会抱怨文件。
我进行了以下实验来验证其是否有效:
main.cpp:
#include <string_view>
#include <vector>
void foo() {
std::vector<std::string_view> v;
v[0] = std::string_view("abc", 1);
}
编译命令:
$ iwyu --version
include-what-you-use 0.17 based on Ubuntu clang version 13.0.1-2ubuntu2.2
$ clang++-13 --version
Ubuntu clang version 13.0.1-2ubuntu2.2
Target: x86_64-pc-linux-gnu
Thread model: posix
InstalledDir: /usr/bin
$ CXX=clang++-13 iwyu -D_FILE_OFFSET_BITS=64 -std=gnu++2a -c main.cpp
main.cpp should add these lines:
#include <ext/alloc_traits.h> // for __alloc_traits<>::value_type
main.cpp should remove these lines:
The full include-list for main.cpp:
#include <ext/alloc_traits.h> // for __alloc_traits<>::value_type
#include <string_view> // for string_view
#include <vector> // for vector
---
如果我将
-Xiwyu --mapping_file=mappings.imp
添加到编译命令中,它会接受 main.cpp
。
然后,我创建了另一个程序:
main_um.cpp:
#include <unordered_map>
#include <vector>
void fie() {
std::vector<std::unordered_map<int, int>> v;
v[0] = {};
}
在这里,我也收到关于
ext/alloc_traits.h
的投诉:
$ CXX=clang++-13 iwyu -D_FILE_OFFSET_BITS=64 -std=gnu++2a -c main_om.cpp -Xiwyu
warning: argument unused during compilation: '-Xiwyu'
main_om.cpp should add these lines:
#include <ext/alloc_traits.h> // for __alloc_traits<>::value_type
main_om.cpp should remove these lines:
The full include-list for main_om.cpp:
#include <ext/alloc_traits.h> // for __alloc_traits<>::value_type
#include <unordered_map> // for unordered_map
#include <vector> // for vector
---
但是添加相同的
-Xiwyu --mapping_file=mappings.imp
会导致它通过。