String literal
目次 |
構文
"
s-char-seq
(オプション)
"
|
(1) | ||||||||
R"
d-char-seq
(オプション)
(
r-char-seq
(オプション)
)
d-char-seq
(オプション)
"
|
(2) | (C++11以降) | |||||||
L"
s-char-seq
(オプション)
"
|
(3) | ||||||||
LR"
d-char-seq
(オプション)
(
r-char-seq
(オプション)
)
d-char-seq
(オプション)
"
|
(4) | (C++11以降) | |||||||
u8"
s-char-seq
(オプション)
"
|
(5) | (C++11以降) | |||||||
u8R"
d-char-seq
(オプション)
(
r-char-seq
(オプション)
)
d-char-seq
(オプション)
"
|
(6) | (C++11以降) | |||||||
u"
s-char-seq
(オプション)
"
|
(7) | (C++11以降) | |||||||
uR"
d-char-seq
(オプション)
(
r-char-seq
(オプション)
)
d-char-seq
(オプション)
"
|
(8) | (C++11以降) | |||||||
U"
s-char-seq
(オプション)
"
|
(9) | (C++11以降) | |||||||
UR"
d-char-seq
(オプション)
(
r-char-seq
(オプション)
)
d-char-seq
(オプション)
"
|
(10) | (C++11以降) | |||||||
説明
| s-char-seq | - | 1つ以上の s-char のシーケンス |
| s-char | - |
以下のいずれか
|
| basic-s-char | - | 基本ソース文字セット (C++23まで) 翻訳文字セット (C++23以降) からの文字。ただし、二重引用符 " 、バックスラッシュ \ 、改行文字は除く |
| d-char-seq | - | 1つ以上の d-char のシーケンス。最大16文字 |
| d-char | - | 基本ソース文字セット (C++23まで) 基本文字セット (C++23以降) からの文字。ただし、括弧、バックスラッシュ、および 空白文字 は除く |
| r-char-seq | - |
1つ以上の
r-char
のシーケンス。ただし、終了シーケンス
)
d-char-seq
"
を含んではならない
|
| r-char | - | 基本ソース文字セット (C++23まで) 翻訳文字セット (C++23以降) からの文字 |
(注:指定されたテキストブロック内に翻訳対象となる実際のテキストコンテンツが含まれていないため、HTML構造のみを保持した状態で出力しています)
| 構文 | 種類 | 型 | エンコーディング | ||||
|---|---|---|---|---|---|---|---|
| (1,2) | 通常の文字列リテラル | const char [ N ] | 通常のリテラルエンコーディング | ||||
| (3,4) | ワイド文字列リテラル | const wchar_t [ N ] | ワイドリテラルエンコーディング | ||||
| (5,6) | UTF-8文字列リテラル |
|
UTF-8 | ||||
| (7,8) | UTF-16文字列リテラル | const char16_t [ N ] | UTF-16 | ||||
| (9,10) | UTF-32文字列リテラル | const char32_t [ N ] | UTF-32 |
上記の表にリストされている型において、 N はエンコードされたコード単位の数であり、これは 以下 で決定されます。
通常の およびUTF-8 (C++11以降) 文字列リテラルは、まとめてナロー文字列リテラルと呼ばれます。
文字列リテラルを評価すると、静的 ストレージ期間 を持つ文字列リテラルオブジェクトが生成されます。すべての文字列リテラルが 非重複オブジェクト に格納されるかどうか、および連続する文字列リテラルの評価が同じオブジェクトを返すか異なるオブジェクトを返すかは未規定です。
文字列リテラルオブジェクトを変更しようとする効果は未定義です。
bool b = "bar" == 3 + "foobar"; // true または false の可能性あり、未規定 const char* pc = "Hello"; char* p = const_cast<char*>(pc); p[0] = 'M'; // 未定義動作
生文字列リテラル
生文字列リテラルは、接頭辞に
// OK: contains one backslash, // equivalent to "\\" R"(\)"; // OK: contains four \n pairs, // equivalent to "\\n\\n\\n\\n" R"(\n\n\n\n)"; // OK: contains one close-parenthesis, two double-quotes and one open-parenthesis, // equivalent to ")\"\"(" R"-()""()-"; // OK: equivalent to "\n)\\\na\"\"\n" R"a( )\ a"" )a"; // OK: equivalent to "x = \"\"\\y\"\"" R"(x = ""\y"")"; // R"<<(-_-)>>"; // Error: begin and end delimiters do not match // R"-()-"-()-"; // Error: )-" appears in the middle and terminates the literal |
(C++11以降) |
初期化
文字列リテラルオブジェクトは、文字列リテラルのシーケンスに対応するコード単位値のシーケンスで初期化されます: s-char s および r-char s (C++11以降) 、さらに終端のヌル文字 (U+0000) が順に付加されます:
T
を文字列リテラルの配列要素型(
上記
の表を参照)とする:
-
v
が
Tの表現可能な値の範囲を超えない場合、エスケープシーケンスは値 v を持つ単一のコード単位を生成する。 -
それ以外の場合、
文字列リテラルが構文
(1)
または
(3)
であり、
(C++11以降)
v
が
Tの基底型に対応する符号なし型の表現可能な値の範囲を超えない場合、エスケープシーケンスは型Tの一意の値を持つ単一のコード単位を生成する。この値は v mod 2 S
に合同である。ここで S はTのビット幅である。 - それ以外の場合、プログラムは不適格となる。
連結 (Concatenation)
隣接する文字列リテラルは、 translation phase 6 (プリプロセス後)で連結されます:
- 二つの文字列リテラルが同じ 種類 である場合、連結された文字列リテラルもその種類になります。
|
(C++11まで) | ||||
|
(C++11以降) |
"Hello, " "world!" // フェーズ6で、2つの文字列リテラルが "Hello, world!" を形成 L"Δx = %" PRId16 // フェーズ4で、PRId16は "d" に展開される // フェーズ6で、L"Δx = %" と "d" が L"Δx = %d" を形成
- ↑ そのような連結をサポートする既知の実装はありません。
未評価文字列
以下のコンテキストでは文字列リテラルが期待されますが、評価は行われません:
| (C++11以降) | |
|
(C++14以降) |
|
(C++20以降) |
| (C++26以降) |
|
非通常の文字列リテラルがこれらの文脈で許可されるかどうかは未規定である 、ただしリテラル演算子名は通常の文字列リテラルを使用しなければならない (C++11以降) 。 |
(C++26まで) |
|
これらの文脈では通常の文字列リテラルのみが許可される。 未評価文字列内の各 ユニバーサル文字名 および各 単純エスケープシーケンス は、それが表す 翻訳文字集合 のメンバで置き換えられる。数値エスケープシーケンスまたは条件付きエスケープシーケンスを含む未評価文字列は不適格である。 |
(C++26以降) |
注記
文字列リテラルは 文字配列の初期化 に使用できます。配列が char str [ ] = "foo" ; のように初期化された場合、 str は文字列 "foo" のコピーを含むことになります。
|
文字列リテラルは、C言語との互換性を保つために非constの char * または wchar_t * へ変換可能かつ代入可能です。C言語では文字列リテラルは char [ N ] および wchar_t [ N ] 型です。このような暗黙的な変換は非推奨です。 |
(C++11まで) |
|
文字列リテラルは非constの
|
(C++11以降) |
文字列リテラルは必ずしもnull終端文字シーケンスではありません:文字列リテラルに埋め込まれたnull文字がある場合、それは複数の文字列を含む配列を表します。
const char* p = "abc\0def"; // std::strlen(p) == 3、ただし配列のサイズは8
文字列リテラル内で16進数エスケープシーケンスの後に有効な16進数桁が続く場合、無効なエスケープシーケンスとしてコンパイルに失敗します。文字列連結を回避策として使用できます:
//const char* p = "\xfff"; // エラー: 16進数エスケープシーケンスが範囲外 const char* p = "\xff""f"; // OK: リテラルは {'\xff','f','\0'} を保持する const char[3]
| 機能テスト マクロ | 値 | 標準 | 機能 |
|---|---|---|---|
__cpp_char8_t
|
202207L
|
(C++23)
(DR20) |
char8_t 互換性と移植性の修正 (UTF-8文字列リテラルからの ( unsigned ) char 配列の初期化 を許可) |
__cpp_raw_strings
|
200710L
|
(C++11) | 生文字列リテラル |
__cpp_unicode_literals
|
200710L
|
(C++11) | Unicode文字列リテラル |
例
#include <iostream> // array1 と array2 は同じ値を含む: char array1[] = "Foo" "bar"; char array2[] = {'F', 'o', 'o', 'b', 'a', 'r', '\0'}; const char* s1 = R"foo( Hello World )foo"; // 以下と同じ const char* s2 = "\nHello\n World\n"; // 以下と同じ const char* s3 = "\n" "Hello\n" " World\n"; const wchar_t* s4 = L"ABC" L"DEF"; // OK, 以下と同じ const wchar_t* s5 = L"ABCDEF"; const char32_t* s6 = U"GHI" "JKL"; // OK, 以下と同じ const char32_t* s7 = U"GHIJKL"; const char16_t* s9 = "MN" u"OP" "QR"; // OK, 以下と同じ const char16_t* sA = u"MNOPQR"; // const auto* sB = u"Mixed" U"Types"; // C++23 以前は実装によってサポートされる場合とされない場合がある; // C++23 以降は不適格 const wchar_t* sC = LR"--(STUV)--"; // OK, raw string literal int main() { std::cout << array1 << ' ' << array2 << '\n' << s1 << s2 << s3 << std::endl; std::wcout << s4 << ' ' << s5 << ' ' << sC << std::endl; }
出力:
Foobar Foobar Hello World Hello World Hello World ABCDEF ABCDEF STUV
不具合報告
以下の動作変更の欠陥報告書は、以前に公開されたC++規格に対して遡及的に適用されました。
| DR | 適用対象 | 公開時の動作 | 修正後の動作 |
|---|---|---|---|
|
CWG 411
( P2029R4 ) |
C++98 |
文字列リテラル内のエスケープシーケンスが
複数のコード単位にマップすることは許可されていなかった |
許可される |
|
CWG 1656
( P2029R4 ) |
C++98 |
文字列リテラル内の数値エスケープシーケンスによって
表される文字が不明確だった |
明確化された |
| CWG 1759 | C++11 |
UTF-8文字列リテラルが
char
で表現不可能な
コード単位を持つ可能性があった |
char はすべてのUTF-8コード単位を表現可能 |
| CWG 1823 | C++98 |
文字列リテラルが区別されるかどうかは
実装定義だった |
区別されるかどうかは未規定であり、同じ
文字列リテラルが異なるオブジェクトを生成する可能性がある |
|
CWG 2333
( P2029R4 ) |
C++11 |
UTF-8/16/32文字列リテラルで数値エスケープシーケンスが
許可されるかどうかが不明確だった |
明確化された |
| CWG 2870 | C++11 |
2つの通常の文字列リテラルの
連結結果が不明確だった |
明確化された |
| P1854R4 | C++98 |
エンコード不可能な文字を含む通常およびワイド文字列リテラルは
条件付きサポートだった |
そのようなリテラルを含むプログラムは不適格 |
| P2029R4 | C++98 |
1. 文字列リテラルがエンコード不可能な文字を
含むことができるかどうかが不明確だった 2. 数値エスケープシーケンスが、それらが表すコード単位が リテラルの配列要素型で表現不可能であるような 文字列リテラルを含むことができるかどうかが不明確だった |
1. 通常およびワイド文字列リテラルに対して
条件付きサポートとして明確化 [1] 2. コード単位が基礎となる型に対応する 符号なし整数型で表現不可能な場合は不適格 |
- ↑ P1854R4は後にDRとして採択され、この解決策を上書きしました。
参考文献
- C++23標準 (ISO/IEC 14882:2024):
-
- 5.13.5 文字列リテラル [lex.string]
- C++20標準 (ISO/IEC 14882:2020):
-
- 5.13.5 文字列リテラル [lex.string]
- C++17標準 (ISO/IEC 14882:2017):
-
- 5.13.5 文字列リテラル [lex.string]
- C++14標準(ISO/IEC 14882:2014):
-
- 2.14.5 文字列リテラル [lex.string]
- C++11標準 (ISO/IEC 14882:2011):
-
- 2.14.5 文字列リテラル [lex.string]
- C++03規格 (ISO/IEC 14882:2003):
-
- 2.13.4 文字列リテラル [lex.string]
- C++98標準 (ISO/IEC 14882:1998):
-
- 2.13.4 文字列リテラル [lex.string]
関連項目
| ユーザー定義リテラル (C++11) | ユーザー定義サフィックスを持つリテラル |
|
C ドキュメント
for
文字列リテラル
|
|