Каково обоснование скобок в С++ 11 исходных строковых литералов R "(...)"?

В С++ 11 есть очень удобная функция, называемая сырыми строковыми литералами, которые представляют собой строки без escape-символов. И вместо этого:

  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"

Но, если вам нужна большая гибкость, у вас есть старые хорошие сменные строковые литералы. Почему стандартный комитет решил загрязнить содержимое каждого необработанного строкового литерала этими абсолютно ненужными скобками? В чем причина этого? Какие плюсы я не упоминал?

Ответ 1

Цель круглых скобок заключается в том, чтобы вы могли указать пользовательский разделитель:

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

В вашем примере и в типичном использовании разделитель просто пуст, поэтому необработанная строка заключена в последовательности R"( и )".

Разрешение произвольных разделителей - это дизайнерское решение, отражающее желание предоставить полное решение без каких-либо странных ограничений или случаев с краями. Вы можете выбрать любую последовательность символов, которая не встречается в вашей строке в качестве разделителя.

Без этого у вас возникнут проблемы, если сама строка содержит что-то вроде " (если вы просто хотели R"..." как синтаксис сырой строки) или )" (если разделитель пуст). Обе из них являются абсолютно обычными и частыми последовательностями символов, особенно в регулярных выражениях, поэтому было бы невероятно раздражать, если бы решение о том, использует ли вы или нет исходную строку, зависит от конкретного содержимого вашей строки.

Помните, что внутри исходной строки нет другого механизма эвакуации, так что лучше всего вы могли бы сделать иначе: объединить фрагменты строкового литерала, что было бы очень непрактичным. Предоставляя настраиваемый разделитель, все, что вам нужно сделать, это выбрать необычную последовательность символов один раз и, возможно, изменить ее в очень редких случаях, когда вы делаете новое редактирование.

Но еще раз подчеркнуть, что даже пустой разделитель уже полезен, так как синтаксис R"(...)" позволяет размещать в вашей строке голые кавычки. Это само по себе довольно выигрыш.