50

)"以下の例では、生の文字列リテラルが2 つの文字で終了しています。
このシーケンス)"は、ある時点でテキストに表示される可能性があり、このシーケンスがテキスト内に見つかった場合でも、文字列を継続させたいと考えています。

R"(  
    Some Text)"  
)";       // ^^

)"終了せずに文字列リテラル内にシーケンスを含めるにはどうすればよいですか?

4

3 に答える 3

31

これは生のリテラルであるため、エスケープは役に立ちませんが、構文は、 のような少し恣意的なフレーズを導入することで、開始と終了を明確に区別できるように設計されていますaha

R"aha(  
    Some Text)"  
)aha";

ちなみに、あなたの例とは反対の、最後にの順序)に注意してください。"


形式に関しては、(標準を調べて) 一見すると、生の文字列リテラルでも通常のリテラルと同じようにエスケープが機能するように見えるかもしれません。そうではないことを知っていることを除いて、ルールに例外が記載されていないのに、どうしてそれが可能でしょうか? 生の文字列リテラルが C++11 で導入されたとき、それは追加の元に戻す変換フェーズを導入する方法でした。たとえば、エスケープの効果を元に戻します。

C++11 §2.5/3

生の文字列の最初と最後の二重引用符の間で、フェーズ 1 と 2 で実行されたすべての変換 (トライグラフ、ユニバーサル文字名、およびライン スプライシング) が元に戻されます。この復帰は、 d-charr-char、または区切り括弧が識別される前に適用されます。

これにより、Unicode 文字仕様 ( のような汎用文字名\u0042) が処理されます。これは、見た目も動作もエスケープのように見えますが、正式には C++ ではエスケープ シーケンスではなく、エスケープ シーケンスではありません。

生の文字列リテラルのコンテンツにカスタム文法規則を使用することにより、真の正式なエスケープが処理されます。むしろ、処理されません! つまり、C++ §2.14.5 では、生の文字列の文法エンティティは次のように定義されています。

" d-char-sequence opt ( r-char-sequence opt ) d-char-sequence opt "

ここで、r-char-sequenceはr -char のシーケンスとして定義され、それぞれが

ソース文字セットの任意のメンバー。ただし、右括弧)の後に最初のd-char-sequence [aha上記のように] (空の場合もある) が続き、その後に二重引用符が続く場合を除く"


本質的に、上記は生の文字列でエスケープを直接使用できないだけでなく (これは重要な点であり、否定的ではなく肯定的です)、Unicode 文字仕様も直接使用できないことを意味します。

間接的に行う方法は次のとおりです。

#include <iostream>
using namespace std;

auto main() -> int
{
    cout << "Ordinary string with a '\u0042' character.\n";
    cout << R"(Raw string without a '\u0042' character, and no \n either.)" "\n";
    cout << R"(Raw string without a '\u0042' character, i.e. no ')" "\u0042" R"(' character.)" "\n";
}

出力:

「B」文字を含む通常の文字列。
'\u0042' 文字を含まず、\n も含まない生の文字列。
「\u0042」文字を含まない生の文字列、つまり「B」文字を含まない文字列。
于 2015-05-18T16:17:18.277 に答える