源文件包含

 
 
C++ 语言
 
 

将其他源文件包含到当前源文件中紧随指令之后的一行。

语法

#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++ 标准库头文件列表