IT이야기

문자열 리터럴 대신 문자열에 대해 사용자 정의 리터럴을 사용할 때의 이점

cyworld 2021. 9. 25. 11:11
반응형

문자열 리터럴 대신 문자열에 대해 사용자 정의 리터럴을 사용할 때의 이점


비고 섹션에서 말했던 SO 문서의 문자열 주제:

사용하는 대신 C ++ (14) 때문에 "foo", 그것을 사용하는 것이 좋습니다 "foo"s로, s변환 문자열 리터럴이다 const char * "foo"std::string "foo".

내가 볼 수있는 유일한 장점은

std::string str = "foo"s;

대신에

std::string str = "foo";

첫 번째 경우 컴파일러는 복사 제거를 수행할 수 있으며(제 생각에는) 이는 두 번째 경우의 생성자 호출보다 빠릅니다.

그럼에도 불구하고 이것은 (아직) 보장되지 않으므로 첫 번째 것은 생성자, 복사 생성자를 호출할 수도 있습니다.

가되는 경우 무시 필요한 사용하는 std::string같은 리터럴

std::string str = "Hello "s + "World!"s;

std::string리터럴 대신 리터럴 을 사용하면 어떤 이점이 const char[]있습니까?


"거의 항상 자동" 군중의 일부인 경우 UDL은 매우 중요합니다. 이를 통해 다음을 수행할 수 있습니다.

auto str = "Foo"s;

따라서 strstd::string아닌 정품 const char*됩니다. 따라서 언제 무엇을 할지 결정할 수 있습니다.

이는 자동 반환 유형 공제에도 중요합니다.

[]() {return "Foo"s;}

또는 모든 형태의 유형 연역, 실제로:

template<typename T>
void foo(T &&t) {...}

foo("Foo"s);

[...] 대신 [...]를 사용하여 볼 수 있는 유일한 이점은 첫 번째 경우 컴파일러가 복사 제거를 수행할 수 있다는 것입니다(제 생각에는). 이는 두 번째 경우의 생성자 호출보다 빠릅니다.

복사 생략은 생성자 호출보다 빠르지 않습니다. 어느 쪽이든, 당신은 객체의 생성자 중 하나를 호출하고 있습니다. 질문은 다음 중 하나입니다 .

std::string str = "foo";

이것은 a std::string를 취하는 생성자에 대한 호출을 유발 합니다 const char*. 그러나 std::string문자열을 자체 저장소에 복사해야 하므로 그렇게 하려면 문자열의 길이를 가져와야 합니다. 그리고 길이를 알지 못하기 때문에 이 생성자는 strlen그것을 얻기 위해 강제로 사용해야 합니다(기술적으로 char_traits<char>::length, 그러나 훨씬 더 빠르지는 않을 것입니다).

대조적으로:

std::string str = "foo"s;

이것은 다음 프로토타입이 있는 UDL 템플릿을 사용합니다.

string operator "" s(const char* str, size_t len);

참조는 컴파일러는 문자열 리터럴의 길이를 알고있다. 따라서 UDL 코드에는 문자열과 크기에 대한 포인터가 전달됩니다. 따라서 a std::string를 취하는 생성자를 호출할 수 있습니다 . 따라서 문자열의 길이를 계산할 필요가 없습니다.const char* size_t

문제의 조언은 리터럴의 모든 사용을 s버전 으로 변환하는 것이 아닙니다 . chars 배열의 제한 사항에 문제가 없으면 사용하십시오. 조언은 리터럴을 a 에 저장하려는 경우 std::string여전히 리터럴이고 모호하지 않은 상태에서 완료하는 것이 가장 좋습니다 const char*.


사용에 대한 조언 "blah"s은 효율성과 관련이 없으며 초보자 코드의 정확성과 관련이 있습니다.

C에 대한 배경 지식이 없는 C++ 초보자는 그 "blah"결과가 합리적인 문자열 유형의 객체 라고 가정하는 경향이 있습니다. 예를 들어, "blah" + 42많은 스크립트 언어에서 작동하는 와 같은 것을 작성할 수 있습니다. 함께 "blah" + 42C ++에서, 그러나, 단지 하나의 문자 배열의 끝을 넘어 어드레싱 정의되지 않은 동작을 초래한다.

그러나 해당 문자열 리터럴이 다음과 같이 작성 "blah"s되면 대신 컴파일 오류가 발생하므로 훨씬 바람직합니다.


또한 UDL을 사용 \0하면 문자열에 더 쉽게 포함할 수 있습니다 .

std::string s = "foo\0bar"s; // s contains a \0 in its middle.
std::string s2 = "foo\0bar"; // equivalent to "foo"s

  1. C++ 문자열 리터럴 strlen을 사용하면 길이를 계산하기 위해 호출 필요가 없습니다 . 컴파일러는 이미 알고 있습니다.
  2. 문자열 데이터가 전역 공간의 메모리를 가리키는 라이브러리 구현을 허용할 수 있습니다. C 리터럴을 사용하면 구성 시 항상 데이터 복사본을 강제로 메모리를 힙해야 합니다.

ReferenceURL : https://stackoverflow.com/questions/38626341/advantages-of-using-user-defined-literal-for-strings-instead-of-string-literal

반응형