CppCoreGuidelines SF.10 避免依赖于隐式包含的变量名
19 November 2023
“Avoid dependencies on implicitly #include
d names”
理由
避免惊讶。避免因为一个包含的头文件改动了,不得不修改 #include
列表。避免因为头文件,造成逻辑上独立的实现细节之家互相依赖。
坏例子
#include <iostream> using namespace std; void use() { string s; cin >> s; // fine getline(cin, s); // error: getline() not defined if (s == "surprise") { // error == not defined // ... } }
<iostream>
会暴露 std::string
的定义(为何?)。但是不会包含整个
<string>
头文件。于是会引起一些初学者的问题:为何 getline(cin, s);
无法工作?为什么 string
无法通过 ==
进行比较判断?
解决方案是显式的添加 #include <string>;
好例子
#include <iostream> #include <string> using namespace std; void use() { string s; cin >> s; // fine getline(cin, s); // fine if (s == "surprise") { // fine // ... } }
注意
有些头文件就是用来收集多个不同头文件的,比如:
// basic_std_lib.h: #include <string> #include <map> #include <iostream> #include <random> #include <vector>
用户可以通过单个 #include
就把以上头文件都包含进来了。
#include "basic_std_lib.h"
此条规则反对隐式包含,但是并不阻止这种有意的头文件聚合设计。
强化
强化手段需要知道头文件里哪些是导出的,哪些是实现细节相关的。在我们有 C++ module 之前,暂时没有什么好的解决方案。