The purpose of the parentheses is to allow you to specify a custom delimiter:
R"foo(Hello World)foo" // the string "Hello World"
In your example, and in typical use, the delimiter is simply empty, so the raw string is enclosed by the sequences R"(
and )"
.
Allowing for arbitrary delimiters is a design decision that reflects the desire to provide a complete solution without weird limitations or edge cases. You can pick any sequence of characters that does not occur in your string as the delimiter.
Without this, you would be in trouble if the string itself contained something like "
(if you had just wanted R"..."
as your raw string syntax) or )"
(if the delimiter is empty). Both of those are perfectly common and frequent character sequences, especially in regular expressions, so it would be incredibly annoying if the decision whether or not you use a raw string depended on the specific content of your string.
Remember that inside the raw string there’s no other escape mechanism, so the best you could do otherwise was to concatenate pieces of string literal, which would be very impractical. By allowing a custom delimiter, all you need to do is pick an unusual character sequence once, and maybe modify it in very rare cases when you make a future edit.
But to stress once again, even the empty delimiter is already useful, since the R"(...)"
syntax allows you to place naked quotation marks in your string. That by itself is quite a gain.