나는 모방 A와 디자인 된 내부 라이브러리를 사용하고 C ++ 라이브러리를 제안 하고, 언젠가 지난 몇 년 동안 나는 볼의 인터페이스를 사용하여 변경 std::string
에를 string_view
.
그래서 새로운 인터페이스에 맞게 코드를 정중하게 변경했습니다. 불행히도, 전달해야 할 것은 std :: string 매개 변수이며 std :: string 반환 값입니다. 그래서 내 코드는 다음과 같이 변경되었습니다.
void one_time_setup(const std::string & p1, int p2) {
api_class api;
api.setup (p1, special_number_to_string(p2));
}
에
void one_time_setup(const std::string & p1, int p2) {
api_class api;
const std::string p2_storage(special_number_to_string(p2));
api.setup (string_view(&p1[0], p1.size()), string_view(&p2_storage[0], p2_storage.size()));
}
나는 정말 (아마도 망치)이 변화가 더 많은 코드 이외의 API 클라이언트, 나를 구입 무엇을 볼 수 없습니다. API 호출은 안전하지 않습니다 (API가 더 이상 매개 변수에 대한 스토리지를 소유하지 않기 때문에). 아마도 프로그램 0 작업을 저장했습니다 (컴파일러가 지금 할 수있는 최적화 작업으로 인해). 작업을 저장하더라도 작업을 저장하더라도 시작 후 또는 어딘가에 큰 루프에서 수행되지 않을 두 개의 할당. 이 API에는 해당되지 않습니다.
그러나이 방법은 예를 들어, 내가 다른 곳에서 볼 수 조언을 따르는 것 이 답변 :
따로, C ++ 17부터 std :: string_view를 위해 const std :: string &을 전달하지 않아야합니다.
나는 주로 최적화의 목적으로 비교적 안전한 객체를 덜 안전한 객체 (기본적으로 영광스러운 포인터 및 길이)로 대체하는 것을 옹호하는 것처럼 보이는 충고가 놀랍습니다.
그럼 언제 해야 string_view 사용될 때, 그리고 그것을해야하지?
답변
- 가치를 얻는 기능이 문자열의 소유권을 가져야합니까? 그렇다면
std::string
(비 const, non-ref)를 사용하십시오. 이 옵션을 사용하면 호출 컨텍스트에서 다시 사용되지 않을 경우 값을 명시 적으로 이동할 수 있습니다. - 기능이 문자열을 읽습니까? 사용 그렇다면
std::string_view
때문이다 (CONST, 비-REF)string_view
처리 할 수std::string
및char*
문제없이 복사하지 않고 쉽게. 모든const std::string&
매개 변수를 대체해야합니다 .
궁극적으로 생성자 를 호출 할 필요 는 없습니다std::string_view
. 변환을 자동으로 처리 std::string
하는 변환 연산자 가 있습니다.
답변
A는 std::string_view
a의 몇 가지 이점 제공 const char*
++ C에 : 달리를 std::string
하는 string_view
- 기억이 없다
- 메모리를 할당하지 않습니다
- 오프셋에서 기존 문자열을 가리킬 수 있으며
- a보다 포인터 간접 레벨이 하나 낮습니다
std::string&
.
즉, string_view는 원시 포인터를 처리하지 않고도 종종 복사를 피할 수 있습니다.
현대 코드에서는 std::string_view
거의 모든 const std::string&
기능 매개 변수 사용을 대체해야합니다 . std::string
변환 연산자를로 선언 하므로 소스 호환 변경 사항이어야합니다 std::string_view
.
문자열보기가 문자열 을 만들어야하는 특정 사용 사례 에서 도움 이되지 않는다고해서 그것이 일반적으로 나쁜 생각임을 의미하지는 않습니다. C ++ 표준 라이브러리는 편의성보다는 일반성에 맞게 최적화되는 경향이 있습니다. 문자열보기를 직접 만들 필요가 없으므로 “안전하지 않은”인수는 유지되지 않습니다.
답변
나는 주로 최적화의 목적으로 비교적 안전한 객체를 덜 안전한 객체 (기본적으로 영광스러운 포인터 및 길이)로 대체하는 것을 옹호하는 것처럼 보이는 충고가 놀랍습니다.
나는 이것이 이것의 목적을 약간 오해하고 있다고 생각합니다. “최적화”이지만 실제로는을 사용하지 않아도되는 것으로 생각해야합니다 std::string
.
C ++ 사용자는 수십 개의 서로 다른 문자열 클래스를 만들었습니다 . 고정 길이 문자열 클래스, 버퍼 크기가 템플릿 매개 변수 인 SSO 최적화 클래스,이를 비교하는 데 사용되는 해시 값을 저장하는 문자열 클래스 등 일부 사람들은 심지어 COW 기반 문자열을 사용합니다. C ++ 프로그래머가 좋아하는 것이 있다면 문자열 클래스를 작성하는 것입니다.
그리고 그것은 C 라이브러리가 만들고 소유 한 문자열을 무시합니다. 벌거 벗은 char*
, 아마 어떤 종류의 크기.
따라서 일부 라이브러리를 작성 중이고를 사용 const std::string&
하면 사용자는 이제 사용중인 문자열을 가져 와서에 복사해야합니다 std::string
. 아마 수십 번.
std::string
의 문자열 별 인터페이스에 액세스하려면 왜 문자열 을 복사 해야 합니까? 그것은 낭비입니다.
string_view
매개 변수로 사용 하지 않는 주요 이유 는 다음과 같습니다.
-
궁극적 인 목표가 문자열을 NUL 종료 문자열 (
fopen
, 등) 을 사용하는 인터페이스로 전달하는 것입니다 .std::string
NUL 종료가 보장됩니다.string_view
그렇지 않습니다. 그리고 NUL로 끝나지 않도록 뷰를 서브 스트링하는 것은 매우 쉽습니다. 하위std::string
문자열 a 는 하위 문자열을 NUL 종료 범위로 복사합니다.정확히이 시나리오를 위해 특수 NUL 종료 string_view 스타일 유형을 작성했습니다. 대부분의 작업을 수행 할 수 있지만 NUL 종료 상태를 위반하는 작업은 수행 할 수 없습니다 (예 : 끝에서 트리밍).
-
평생 문제. 실제로 복사해야
std::string
하거나 문자 배열이 함수 호출보다 오래 지속되어야하는 경우을 사용 하여이 상태를 미리 밝히는 것이 가장 좋습니다const std::string &
. 또는std::string
값 매개 변수로 사용하십시오. 이런 식으로 이미 그러한 문자열을 가지고 있다면 즉시 소유권을 주장 할 수 있으며, 발신자가 복사본을 보관할 필요가없는 경우 문자열로 이동할 수 있습니다.