Namespaces
Variants

Source file inclusion

From cppreference.net
C++ language
General topics
Flow control
Conditional execution statements
Iteration statements (loops)
Jump statements
Functions
Function declaration
Lambda function expression
inline specifier
Dynamic exception specifications ( until C++17* )
noexcept specifier (C++11)
Exceptions
Namespaces
Types
Specifiers
constexpr (C++11)
consteval (C++20)
constinit (C++20)
Storage duration specifiers
Initialization
Expressions
Alternative representations
Literals
Boolean - Integer - Floating-point
Character - String - nullptr (C++11)
User-defined (C++11)
Utilities
Attributes (C++11)
Types
typedef declaration
Type alias declaration (C++11)
Casts
Memory allocation
Classes
Class-specific function properties
Special member functions
Templates
Miscellaneous

現在のソースファイルに、他のソースファイルをディレクティブの直後の行に挿入します。

目次

翻訳内容: - 「Contents」→「目次」 - その他のテキスト(Syntax、Explanation、Notes、Example、Defect reports、See also)はC++関連の専門用語として翻訳せず、原文のまま保持しました - HTMLタグ、属性、数値、リンクはすべて変更せず保持 - 書式設定は完全に維持

構文

#include < h-char-sequence > new-line (1)
#include " q-char-sequence " new-line (2)
#include pp-tokens new-line (3)
__has_include ( " q-char-sequence " )
__has_include ( < h-char-sequence > )
(4) (C++17以降)
__has_include ( string-literal )
__has_include ( < h-pp-tokens > )
(5) (C++17以降)
1) 一意に識別されるヘッダーを h-char-sequence で検索し、ディレクティブをヘッダーの全内容で置き換えます。
2) q-char-sequence によって識別されるソースファイルを検索し、ディレクティブをそのソースファイルの内容全体で置き換えます。 (1) にフォールバックし、 q-char-sequence をヘッダー識別子として扱う場合があります。
3) もし (1) (2) のどちらにもマッチしない場合、 pp-tokens はマクロ置換の対象となります。置換後のディレクティブは再度 (1) または (2) とのマッチングが試行されます。
4) ヘッダーファイルまたはソースファイルがインクルード可能かどうかをチェックします。
5) もし (4) が一致しない場合、 h-pp-tokens はマクロ置換を受けます。置換後のディレクティブは再度 (4) との一致が試みられます。
new-line - 改行文字
h-char-sequence - 1つ以上の h-char のシーケンス。以下のいずれかの出現は、実装定義のセマンティクスで条件付きサポートされる:
  • 文字 '
  • 文字 "
  • 文字 \
  • 文字シーケンス //
  • 文字シーケンス /*
h-char - ソース文字セット (C++23まで) 翻訳文字セット (C++23以降) の任意のメンバー(改行と > を除く)
q-char-sequence - 1つ以上の q-char のシーケンス。以下のいずれかの出現は、実装定義のセマンティクスで条件付きサポートされる:
  • 文字 '
  • 文字 \
  • 文字シーケンス //
  • 文字シーケンス /*
q-char - ソース文字セット (C++23まで) 翻訳文字セット (C++23以降) の任意のメンバー(改行と " を除く)
pp-tokens - 1つ以上の プリプロセッシングトークン のシーケンス
string-literal - 文字列リテラル
h-pp-tokens - 1つ以上の プリプロセッシングトークン のシーケンス( > を除く)

説明

1) h-char-sequence によって一意に識別されるヘッダーを一連の場所から検索し、そのディレクティブをヘッダーの内容全体で置き換えます。場所の指定方法やヘッダーの識別方法は実装定義です。
2) そのディレクティブを q-char-sequence で識別されるソースファイルの内容全体で置き換える。指定されたソースファイルは実装定義の方法で検索される。
この検索がサポートされていない場合、または検索が失敗した場合、ディレクティブは元のディレクティブからの同一の含まれるシーケンス( (1) を含む > 文字がある場合)で (1) の構文として再処理されます。
3) ディレクティブ内の include に続く前処理トークンは、通常のテキストと同様に処理されます(つまり、現在マクロ名として定義されている各識別子は、その置換リストの前処理トークンで置き換えられます)。
すべての置換が行われた後のディレクティブが前述の2つの形式のいずれにも一致しない場合、動作は未定義です。
前処理トークンのシーケンスが < > の前処理トークンペア、または " 文字のペアの間で単一のヘッダー名前処理トークンに結合される方法は実装定義である。
4) h-char-sequence または q-char-sequence で識別されるヘッダまたはソースファイルは、その前処理トークン列が構文 (3) pp-tokens であるかのように検索されますが、それ以上のマクロ展開は行われません。
  • そのようなディレクティブが #include ディレクティブの構文要件を満たさない場合、プログラムは不適格です。
  • それ以外の場合、 __has_include 式は、ソースファイルの検索が成功すれば 1 に、検索が失敗すれば 0 に評価されます。
5) この形式は、構文 (4) が一致しない場合にのみ考慮され、その場合、プリプロセストークンは通常のテキストと同様に処理されます。

header-name によって識別されるヘッダ(すなわち、 < h-char-sequence > または " q-char-sequence " )がインポート可能なヘッダである場合、 #include プリプロセッシングディレクティブが以下の形式の import directive で置き換えられるかどうかは実装定義である:

import header-name ; new-line

(C++20以降)

__has_include #if および #elif の式内で展開可能です。 #ifdef #ifndef #elifdef #elifndef (C++23以降) および defined によって定義済みマクロとして扱われますが、それ以外の場所では使用できません。

注記

典型的な実装では、構文 (1) に対して標準インクルードディレクトリのみを検索します。標準C++ライブラリと標準Cライブラリは、これらの標準インクルードディレクトリに暗黙的に含まれています。標準インクルードディレクトリは通常、コンパイラオプションを通じてユーザーが制御できます。

構文 (2) の意図は、実装によって制御されないファイルを検索することです。典型的な実装では、まず現在のファイルが存在するディレクトリを検索し、その後 (1) にフォールバックします。

ファイルがインクルードされると、それは 翻訳フェーズ 1-4によって処理され、これにはネストされた #include ディレクティブの再帰的な展開が含まれる場合があり、実装定義のネスト制限に達するまで続きます。同じファイルの重複インクルードや、ファイルが直接的または間接的に自身をインクルードした際の無限再帰を防ぐために、 ヘッダガード が一般的に使用されます:ヘッダ全体を以下のように囲みます

#ifndef FOO_H_INCLUDED /* any name uniquely mapped to file name */
#define FOO_H_INCLUDED
// ファイルの内容がここに記述されます
#endif

多くのコンパイラは非標準の pragma #pragma once も同様の効果で実装しています:同じファイル(ファイルの同一性はOS固有の方法で決定される)が既にインクルードされている場合、そのファイルの処理を無効にします。

q-char-sequence または h-char-sequence 内のエスケープシーケンスに類似する文字シーケンスは、実装によっては、エラーとなる場合、エスケープシーケンスに対応する文字として解釈される場合、または全く異なる意味を持つ場合があります。

__has_include の結果が 1 であることは、指定された名前のヘッダまたはソースファイルが存在することを意味するのみです。これは、そのヘッダやソースファイルがインクルードされた際にエラーが発生しないことや、有用な内容を含んでいることを保証するものではありません。例えば、C++14モードとC++17モードの両方をサポートするC++実装(かつC++14モードで準拠した拡張として __has_include を提供する場合)では、C++14モードにおいて __has_include ( < optional > ) 1 を返す可能性がありますが、実際には #include <optional> がエラーを引き起こす場合があります。

#if __has_include(<optional>)
    #include <optional>
    #define has_optional 1
    template<class T>
    using optional_t = std::optional<T>;
#elif __has_include(<experimental/optional>)
    #include <experimental/optional>
    #define has_optional -1
    template<class T>
    using optional_t = std::experimental::optional<T>;
#else
    #define has_optional 0
    template<class V>
    class optional_t
    {
        V v{};
        bool has{};
    public:
        optional_t() = default;
        optional_t(V&& v) : v(v), has{true} {}
        V value_or(V&& alt) const&
        {
            return has ? v : alt;
        }
        // etc.
    };
#endif
#include <iostream>
int main()
{
    if (has_optional > 0)
        std::cout << "<optional> is present\n";
    else if (has_optional < 0)
        std::cout << "<experimental/optional> is present\n";
    else
        std::cout << "<optional> is not present\n";
    optional_t<int> op;
    std::cout << "op = " << op.value_or(-1) << '\n';
    op = 42;
    std::cout << "op = " << op.value_or(-1) << '\n';
}

出力:

<optional> is present
op = -1
op = 42

不具合報告

以下の動作変更の欠陥報告書は、以前に公開されたC++規格に対して遡及的に適用されました。

DR 適用対象 公開時の動作 正しい動作
CWG 787 C++98 エスケープシーケンスが
q-char-sequence または h-char-sequence 内に存在する場合の動作は未定義
条件付きサポートとなる

関連項目

C++標準ライブラリヘッダーファイルの一覧
Cドキュメント for ソースファイルインクルード