두 문자열 리터럴 연결


121

Koenig의 Accelerated C ++를 읽고 있습니다. 그는 "새로운 아이디어는 +를 사용하여 문자열과 문자열 리터럴을 연결할 수 있다는 것입니다. 또는 그 문제에 대해 두 문자열 (하지만 두 문자열 리터럴은 아님)을 연결할 수 있습니다.

좋아, 이건 말이 돼. 이제이를 조명하기위한 두 개의 개별 연습으로 넘어갑니다.

다음 정의가 유효합니까?

const string hello = "Hello";

const string message = hello + ",world" + "!";

이제 위의 내용을 실행 해 보았습니다. 그래서 행복했습니다.

그런 다음 다음 운동을 시도했습니다.

const string exclam = "!";

const string message = "Hello" + ",world" + exclam;

이것은 작동하지 않았습니다. 이제 두 개의 문자열 리터럴을 연결할 수 없다는 사실과 관련이 있다는 것을 이해합니다.하지만 첫 번째 예제를 작동하게 만든 이유 ( ", world"및 "! "두 개의 문자열 리터럴? 이것이 작동하지 않았어야 했습니까?) 그러나 두 번째는 아닙니다.


4
const string message = "Hello" ",world" + exclam(예 : 첫 번째 생략 +) 잘 작동합니다.
n0rd

1
@Joe- "Hello" + ", world!"당신이 할 수있을 때 왜 누군가가 글을 쓰 겠는가 "Hello, world!". 평소와 같이 C ++에는 인식 된 문제에 대한 훌륭하고 간단한 해결 방법이 있습니다. :-)
Bo Persson

2
@Bo 내가 생각할 수있는 유일한 것은 정의를 사용하는 경우입니다 (#define)
Joe Phillips

@Joe 그럼에도 불구하고 당신은 "Hello" ", world!"(없이 +) 쓸 가능성이 더 큽니다 . C ++에 대해 제기 할 수있는 많은 불만이 있지만 여기에서 처리하는 것이 그중 하나라고 생각하지 않습니다. 마치 당신이 썼던 것과 똑같고 1 / 3 + 1.5, 나눗셈이 완전한 나눗셈이기 때문에 불평했습니다. 좋든 나쁘 든 이것이 대부분의 언어가 작동하는 방식입니다.
James Kanze

2
@Bo Persson 실제로이 기능 "hello" " world" == "hello world"은 긴 문자열을 작성해야하고 창 밖으로 나가는 것을 원하지 않거나 줄 길이를 제한하려는 경우에 유용합니다. 또는 문자열 중 하나가 매크로에 정의 된 경우.
Dimitar Slavchev 2012

답변:


140
const string message = "Hello" + ",world" + exclam;

+연산자는 왼쪽에서 오른쪽으로있다 연관성, 해당 괄호 발현하므로 :

const string message = (("Hello" + ",world") + exclam);

당신은 두 개의 문자열 리터럴을 볼 수 있듯이 "Hello"",world"따라서, 먼저 오류를 "추가"됩니다.

연결되는 처음 두 문자열 중 하나는 std::string객체 여야 합니다.

const string message = string("Hello") + ",world" + exclam;

또는 +식의 해당 부분을 괄호로 묶어 두 번째 항목 을 먼저 평가할 수 있습니다.

const string message = "Hello" + (",world" + exclam);

첫 번째 예제 ( hello + ",world" + "!")가 작동하는 것은 std::string( hello)가 맨 왼쪽에있는 인수 중 하나 이기 때문 +입니다. 그+ , 결과는 std::string연결된 문자열 이있는 객체이고 그 결과 std::string"!".


에 관해서는 이유 두 개의 문자열 리터럴을 사용하여 연결할 수 없습니다 +, 그것은 문자열 리터럴 문자 단지 배열이기 때문이다 (A const char [N]여기서 N널 터미네이터를 들어, 문자열을 더한 길이)입니다. 대부분의 컨텍스트에서 배열을 사용하면 초기 요소에 대한 포인터로 변환됩니다.

그래서 당신이하려고 할 때 "Hello" + ",world" , 당신이 정말로하려는 것은 두 개의 const char*s를 함께 더하는 것입니다. 이것은 불가능합니다 (두 포인터를 함께 추가한다는 것은 무엇을 의미합니까?). 그렇다면 당신이 무엇을하지 않을 것입니까? 그것을 원했습니다.


당신 수 있습니다문자열 리터럴을 나란히 배치하여 연결할 . 예를 들어 다음 두 가지는 동일합니다.

"Hello" ",world"
"Hello,world"

이것은 여러 줄로 나누려는 긴 문자열 리터럴이있는 경우 유용합니다. 그래도 문자열 리터럴이어야합니다 . const char*포인터 나 const char[N]배열 에서는 작동하지 않습니다 .


3
또한 const string message = "Hello" + (",world"+exclam);명시 괄호로 인해 작동합니다 (단어입니까?).
Chinmay Kanchi

1
첫 번째 예제가 작동하는 이유를 지적하면 더 완벽 할 수 있습니다.const string message = ((hello + ",world") + "!");
Mark Ransom

감사합니다! 나는 그것이 왼쪽에서 오른쪽으로의 연관성과 관련이 있다고 생각했지만 확실하지 않았고이 의미 적 차이는 나에게 그다지 이해가되지 않았다. 답변 감사합니다!
Arthur Collé

2
나는 말할 것 "Hello" ",world"구문이 여러 줄에 침입에 대한뿐만 아니라 문자열 리터럴 중 하나가 (심지어 둘 또는) 매크로하지 않을 때 유용하다. 그런 다음 컴파일 타임에 연결이 발생합니다.
Melebius

8

항상 유형에 주의를 기울여야합니다 .

그들은 모두 문자열처럼 보인다,하지만 "Hello"하고 ",world"있다 리터럴 .

그리고 당신의 예에서, exclamA는 std::string객체.

C ++에는 std::string개체 를 가져와 다른 문자열을 추가 하는 연산자 오버로드가 있습니다. std::string객체를 리터럴과 연결하면 리터럴에 대한 적절한 캐스팅이 수행됩니다.

그러나 두 개의 리터럴을 연결하려고하면 컴파일러는 두 개의 리터럴을 취하는 연산자를 찾을 수 없습니다.


a 를 다른 , 문자 배열 또는 단일 문자 와 연결하기위한 오버로드를 제공하는 std :: operator + 를 참조하십시오 . std::stringstd::string
DavidRR 2014

7

두 번째 예제는 operator +두 개의 문자열 리터럴 이 없기 때문에 작동하지 않습니다 . 문자열 리터럴은 유형 string이 아니라 유형 const char *입니다. 두 번째 예제는 다음과 같이 수정하면 작동합니다.

const string message = string("Hello") + ",world" + exclam;

4

C ++ 14부터 두 개의 실제 문자열 리터럴을 사용할 수 있습니다 .

const string hello = "Hello"s;

const string message = hello + ",world"s + "!"s;

또는

const string exclam = "!"s;

const string message = "Hello"s + ",world"s + exclam;

2

경우 1의 경우 작업 순서로 인해 다음을 얻습니다.

(안녕하세요 + ", 세계") + "!" hello + "!"로 해결됩니다. 그리고 마침내 안녕하세요

James가 언급했듯이 케이스 2의 경우 다음을 얻습니다.

( "Hello"+ ", world") + 두 문자열 리터럴의 연결 인 느낌표.

분명 희망 :)


1

문자열 (정확히 말하자면 std::string)과 문자 리터럴 의 차이점 은 후자의 경우 +정의 된 연산자 가 없다는 것입니다 . 이것이 두 번째 예제가 실패하는 이유입니다.

첫 번째 경우 컴파일러는 operator+첫 번째 인수가 a string이고 두 번째 인수가 문자 리터럴 ( const char*) 인 적합한 것을 찾을 수 있으므로이를 사용했습니다. 해당 작업의 결과는 다시 string이므로 추가 "!"할 때 동일한 트릭을 반복 합니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.