C ++ 11의 원시 문자열 리터럴 R“(…)”에서 괄호를 사용하는 이유는 무엇입니까?
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 Kerrek의 대답은 훌륭하지만 불행히도 대답이 아닙니다. 나는 그것이 어떻게 작동하고 어떤 이점을 제공하는지 이해한다고 이미 설명했기 때문에. 이 질문을 한 지 5 년이 지났지 만 아직 답이 없습니다. 그리고 저는이 결정에 여전히 실망합니다. 이것은 맛의 문제라고 말할 수 있지만 나는 동의하지 않을 것입니다. 얼마나 많은 공백을 사용하고, 변수의 이름을 어떻게 지정합니까, 이것이 SomeFunction()
아니면 some_function()
맛의 문제입니다. 그리고 한 스타일에서 다른 스타일로 정말 쉽게 전환 할 수 있습니다.
하지만 이건? .. 오랜 세월이 지난 후에도 여전히 어색하고 서투른 느낌입니다. 아니요, 이건 맛이 아닙니다. 이것은 우리가 어떤 경우에도 가능한 모든 경우를 어떻게 다루고 싶은지에 관한 것입니다. 우리는 Windows 특정 경로, 정규식 또는 여러 줄 문자열 리터럴을 작성해야 할 때마다 이러한 추악한 괄호를 작성해야했습니다. 그리고 무엇을 위해? .. 우리가 실제로 "
문자열 을 넣어야하는 드문 경우를 위해 ? 나는 그들이 이런 식으로 그것을하기로 결정한위원회 회의에 있었으면 좋겠다. 그리고 저는이 정말 나쁜 결정에 강하게 반대 할 것입니다. 나는 원한다. 이제 우리는 멸망했습니다.
여기까지 읽어 주셔서 감사합니다. 이제 기분이 조금 나아졌습니다.
UPD2 다음은 두 가지 모두 기존보다 훨씬 낫다고 생각하는 대체 제안입니다.
제안 1. 파이썬에서 영감을 얻었습니다. 삼중 따옴표가있는 문자열 리터럴을 지원할 수 없습니다.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"#"
.
이 제안에 문제가 있습니까?
다른 답변에서 설명했듯이 "
또는 )"
, 또는 실제로 문자열 자체에 나타날 수있는 닫는 시퀀스의 경우 구문 분석 모호성을 피하기 위해 따옴표에 추가로 뭔가가 있어야 합니다.
구문 선택에 관해서는, 구문 선택이 차선책 이라는 데 동의 하지만 일반적으로 괜찮습니다 ( "일이 더 나빠질 수 있습니다"라고 생각할 수 있습니다). 사용 단순성과 구문 분석 단순성 사이의 좋은 절충안이라고 생각합니다.
제안 1 . 파이썬에서 영감을 얻었습니다. 삼중 따옴표가있는 문자열 리터럴을 지원할 수 없습니다.
R "" "실제로 자주 사용하지 않는 삼중 따옴표를 제외한 모든 내용." ""
"실제로 자주 사용하지 않는 인용구"라는 문제가 있습니다. 첫째, 원시 문자열의 바로 생각은 표현하는 것입니다 원료 가없이 텍스트 파일에있는 것 같은 즉 정확히 문자열을 어떤 관계없이 문자열 내용의 문자열에 대한 수정. 둘째, 구문은 일반적이어야합니다. 즉, "거의 원시 문자열"등과 같은 변형을 추가하지 않아야합니다.
이 구문으로 인용문 하나를 어떻게 작성 하시겠습니까? 두 개의 따옴표? 참고-특히 코드가 문자열 및 구문 분석을 처리 할 때 매우 일반적인 경우입니다.
제안 2 .
R "delim"문자열의 내용 "delim".
R ""더 좋아 보이지 않나요? "".
R "#"여기에 큰 따옴표가 있습니다 : "", 감사합니다 "#".
글쎄, 이것은 더 나은 후보가 될 수 있습니다. 하지만 한 가지 일반적인 경우 (그리고 받아 들여지는 구문에 대한 동기 부여 사례라고 생각합니다)는 큰 따옴표 문자 자체가 매우 일반적이며 이러한 경우에는 원시 문자열이 유용해야한다는 것입니다.
따라서 일반적인 문자열 구문을 살펴 보겠습니다.
s1 = "\"";
s2 = "\"quoted string\"";
예를 들어 "x"를 delim으로 사용하는 구문 :
s1 = R"x"""x";
s2 = R"x""quoted string""x";
허용되는 구문 :
s1 = R"(")";
s2 = R"("quoted string")";
Yes, I agree that the brackets introduce some annoying visual effect. So I suspect the authors of the syntax were after the idea that the additional "delim" in this case will be rarely needed, since )"
appears not very often inside a string. But OTOH, trailing/leading/isolated quotes are quite often, so e.g. your proposed syntax (#2) would require some delim
more often, which in turn would require more often changing it from R""..""
to R"delim"..."delim"
. Hope you get the idea.
Could the syntax be better? I personally would prefer an even simpler variant of syntax:
Rdelim"string contents"delim;
With the above examples:
s1 = Rx"""x;
s2 = Rx""quoted string""x;
However to work correctly (if its possible at all in current grammar), this variant would require limiting the character set for the delim
part, say to letters/digits only (because of existing operators), and maybe some further restrictions for the initial character to avoid clashes with possible future grammar.
So I believe a better choice could have been made, although nothing significantly better can be done in this case.
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.
'Development Tip' 카테고리의 다른 글
!! 1 ==“1”이 true이고 !! 2 ==“2”가 false 인 이유는 무엇입니까? (0) | 2020.11.12 |
---|---|
버튼으로 div 표시 / 숨기기 전환? (0) | 2020.11.12 |
테이블의 모든 행을 어떻게 반복 할 수 있습니까? (0) | 2020.11.11 |
파이썬 pdb-루프 건너 뛰기 (0) | 2020.11.11 |
iOS 9 Safari : 스크롤하는 동안 요소를 고정 위치로 변경하면 스크롤이 멈출 때까지 페인트되지 않습니다. (0) | 2020.11.11 |