源文件包含
来自cppreference.com
< cpp | preprocessor
将其他源文件包含到当前源文件中紧随指令之后的一行。
语法
#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
参阅
cpp/header | C++ 标准库头文件列表 |