81

C++11 で導入された生の文字列リテラルと呼ばれる非常に便利な機能があります。これはエスケープ文字のない文字列です。そして、これを書く代わりに:

  regex mask("\\t[0-9]+\\.[0-9]+\\t\\\\SUB");

これを簡単に書くことができます:

  regex mask(R"(\t[0-9]+\.[0-9]+\t\\SUB)");

かなり読みやすい。ただし、生の文字列リテラルを定義するために配置する必要がある文字列を囲む余分な括弧に注意してください。

私の質問は、なぜこれらが必要なのですか? 私にとって、それは非常に醜く、非論理的に見えます。ここに私が見る短所があります:

  • リテラルをよりコンパクトにするために機能全体が使用されている間、余分な冗長性
  • リテラルの本体と定義記号を区別するのが難しい

それが私が難しい区別によって意味するものです:

"good old usual string literal"
 ^-    body inside quotes   -^

R"(new strange raw string literal)"
   ^- body inside parenthesis  -^

そして、ここにプロがあります:

  • 柔軟性が向上し、生の文字列で使用できる文字数が増えました。特に区切り文字を使用した場合:"delim( can use "()" here )delim"

しかし、もっと柔軟性が必要な場合は、古くて良いエスケープ可能な文字列リテラルがあります。標準委員会が、すべての生の文字列リテラルの内容をこれらの絶対に不要な括弧で汚染することを決定したのはなぜですか? その背後にある理論的根拠は何でしたか? 私が言及しなかった長所は何ですか?

UPDケレックの答えは素晴らしいですが、残念ながら答えではありません。すでに説明したので、それがどのように機能し、どのような利点があるかを理解しています. この質問をしてから5年が経ちましたが、いまだに答えがありません。そして、私はまだこの決定に不満を感じています。これは好みの問題だと言えますが、私はそうは思いません。いくつのスペースを使用するか、変数にどのように名前を付けるか、これかSomeFunction()-some_function()これは好みの問題です。そして、あるスタイルから別のスタイルに簡単に切り替えることができます。

しかし、これは?..何年経ってもまだぎこちなく、ぎこちなく感じます。いいえ、これは味の問題ではありません。これは、可能な限りすべてのケースをカバーしたいということです。Windows 固有のパス、正規表現、または複数行の文字列リテラルを記述する必要があるたびに、これらの醜い括弧を記述する運命にありました。"そして何のために?..実際に文字列を入れる必要があるまれなケースのために? 彼らがこのようにすることを決定したその委員会に私が参加していたらよかったのにと思います。そして、私はこの本当に悪い決定に強く反対します. 私は望む。今、私たちは運命にあります。

ここまで読んでいただきありがとうございます。今は少し気分が良くなりました。

UPD2これが私の代替案です。どちらも既存のものよりもはるかに優れていると思います。

提案 1. python に触発されました。三重引用符を含む文字列リテラルはサポートできません:R"""Here is a string literal with any content, except for triple quotes, which you don't actually use that often."""

提案 2. 常識に触発されました。現在のものと同様に、可能なすべての文字列リテラルをサポートします: R"delim"content of string"delim". 区切り文字が空の場合: R""Looks better, doesn't it?"". 空の生の文字列: R"""". 二重引用符付きの生の文字列: R"#"Here are double quotes: "", thanks"#".

これらの提案に何か問題はありますか?

4

2 に答える 2

107

括弧の目的は、カスタム区切り文字を指定できるようにすることです。

R"foo(Hello World)foo"   // the string "Hello World"

R"(あなたの例では、通常の使用では、区切り文字は単に空であるため、生の文字列はシーケンスとで囲まれています)"

任意の区切り文字を許可することは、奇妙な制限や特殊なケースのない完全なソリューションを提供したいという願望を反映する設計上の決定です。文字列に含まれていない任意の文字列を区切り文字として選択できます。

これがないと、文字列自体に(生の文字列構文として必要な場合) または"(区切り文字が空の場合) のようなものが含まれている場合に問題が発生します。これらは両方とも、特に正規表現では、完全に一般的で頻繁に使用される文字シーケンスであるため、生の文字列を使用するかどうかの決定が文字列の特定の内容に依存しているとしたら、非常に面倒です。R"...")"

生の文字列の内部には他のエスケープ メカニズムがないことを思い出してください。それ以外の場合にできる最善の方法は、文字列リテラルの断片を連結することでした。これは非常に非現実的です。カスタム区切り文字を許可することで、通常とは異なる文字シーケンスを 1 回選択するだけで済み、将来の編集時に非常にまれなケースでそれを変更することができます

しかし、もう一度強調しておきますが、このR"(...)"構文では文字列にネイキッド クォーテーション マークを配置できるため、空の区切り文字でさえもすでに役に立ちます。それ自体はかなりの利益です。

于 2013-09-29T10:25:18.110 に答える