将其他源文件包含到当前源文件中紧随指令之后的一行。
语法
#include < 文件名> | (1) | |
#include " 文件名" | (2) | |
has_include ( " 文件名 " )
has_include ( < 文件名 > ) | (3) | (C++17 起) |
容许任何预处理记号(宏常量或表达式)作为给 #include
和 __has_include
(C++17 起)的实参,只要它们展开成 <
>
或 "
"
所环绕的字符序列即可。
解释
1,2) 将 文件名 所标识的源文件包含到当前源文件中紧随指令后的一行。找不到文件的情况下,程序非良构。
1) 以由实现定义的方式搜索文件。此语法的意图是搜索由实现所掌控的文件。典型实现仅搜索标准包含目录。这些标准包含目录中隐含地包含标准 C++ 库和标准 C 库。用户通常能通过编译器选项来控制标准包含目录。
2) 以由实现定义的方式搜索文件。此语法的意图是搜索不被实现所掌控的文件。典型实现首先于当前文件所在的目录搜索,然后仅当找不到文件时,才在 (1) 中的标准包含目录搜索。
3) 预处理器常量表达式,若找到文件名则求值为 1,而若找不到则求值为 0。若其实参不是给 #include
指令的有效实参,则程序非良构。
注意
包含一个文件时,它将经过翻译阶段 1-4 的处理,这可能递归地包含嵌套 #include
指令的展开。为避免(可能传递性地)重复包含相同文件,和由文件包含自身造成的无限递归,常使用头文件防护:整个头文件被包装在下列结构中
- #ifndef FOO_H_INCLUDED /* 任何唯一地映射到文件的名称 */
- #define FOO_H_INCLUDED
- // 文件内容在此
- #endif
许多编译器亦实现有类似效果的非标准 编译选项(pragma) #pragma once:若已包含了同一文件(这里以特定于 OS 的方式确定文件的身份),则禁止处理该文件。
1 的 has_include
结果仅表明存在有指定名称的头或源文件。它并不意味着包含该头或源文件时不会导致错误,或其会包含任何有意的内容。例如在同时支持 C++14 和 C++17 模式(并在其 C++14 模式作为一项遵从标准的扩展而提供 has_include)的 C++ 实现上,__has_include(<optional>) 在 C++14 模式中可为 1,但实际上 #include <optional> 可能导致错误。
示例
运行此代码
- #if __has_include(<optional>)
- # include <optional>
- # define have_optional 1
- namespace guard { using std::optional; }
- #elif __has_include(<experimental/optional>)
- # include <experimental/optional>
- # define have_optional 1
- # define experimental_optional 1
- namespace guard { using std::experimental::optional; }
- #else
- # define have_optional 0
- #endif
- #include <iostream>
- int main()
- {
- if (have_optional)
- std::cout << "<optional> is present.\n";
- int x = 42;
- #if have_optional == 1
- guard::optional<int> i = x;
- #else
- int* i = &x;
- #endif
- std::cout << "i = " << *i << '\n';
- }
可能的输出:
- <optional> is present.
- i = 42