ソースファイルのインクルード
ディレクティブの直後の行に、現在のソースファイルに別のソースファイルをインクルードします。
目次 |
[編集] 構文
#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以降) | |||||||
| 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つ以上の プリプロセッサートークン。ただし > を除く。 |
[編集] 説明
|
ヘッダー名(つまり `<` h-char-sequence `>` または `"` q-char-sequence `"`)によって識別されるヘッダーがインポート可能である場合、`#include` プリプロセッサディレクティブが、代わりに以下の形式の `import` ディレクティブに置き換えられるかどうかは実装定義です。
|
(C++20以降) |
`__has_include` は、 `#if` および `#elif` の式の中で展開できます。 `#ifdef`、`#ifndef`(C++23以降では `#elifdef`、`#elifndef`)、および `defined` によって定義済みマクロとして扱われますが、それ以外の場所では使用できません。
[編集] 注意
典型的な実装では、構文 (1) に対して標準インクルードディレクトリのみを検索します。標準C++ライブラリおよび標準Cライブラリは、これらの標準インクルードディレクトリに暗黙的に含まれます。標準インクルードディレクトリは、通常、コンパイラオプションを通じてユーザーが制御できます。
構文 (2) の意図は、実装によって制御されないファイルを検索することです。典型的な実装では、まず現在のファイルの場所にあるディレクトリを検索し、次に (1) にフォールバックします。
ファイルがインクルードされると、翻訳フェーズ1~4によって処理されます。これには、実装定義のネスト制限まで、ネストされた `#include` ディレクティブの展開が再帰的に含まれる場合があります。同じファイルが繰り返しインクルードされることや、ファイルがそれ自体を(おそらく間接的に)インクルードする場合の無限再帰を避けるために、*ヘッダーガード*が一般的に使用されます。ヘッダー全体が以下でラップされます。
#ifndef FOO_H_INCLUDED /* any name uniquely mapped to file name */ #define FOO_H_INCLUDED // contents of the file are here #endif
多くのコンパイラは、非標準の `pragma` `#pragma once` も同様の効果で実装しています。これは、同じファイル(ファイルの同一性はOS固有の方法で決定される)が既にインクルードされている場合、そのファイルの処理を無効にします。
q-char-sequence または h-char-sequence でエスケープシーケンスに似た文字シーケンスが現れた場合、実装によってはエラーになったり、エスケープシーケンスに対応する文字として解釈されたり、まったく異なる意味を持つ場合があります。
`__has_include` の結果が 1 であることは、指定された名前のヘッダーまたはソースファイルが存在することのみを意味します。そのヘッダーまたはソースファイルをインクルードした場合にエラーが発生しないことや、有用な内容が含まれることを意味するわけではありません。たとえば、C++14モードとC++17モードの両方をサポートし、C++14モードで `__has_include` を準拠拡張として提供するC++実装では、`__has_include
[編集] 例
#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ドキュメント: ソースファイルのインクルード
|