1

Тема: string_view чи розумний вказівник на string

Цікаво, що краще: string_view чи розумний вказівник на string?
За умови, що створюються лише для читання.
Чи є між ними різниця в сенсі швидкості та використання пам'яті?

2

Re: string_view чи розумний вказівник на string

Якби один завжди був "кращим", другого б не існувало.

3

Re: string_view чи розумний вказівник на string

Vitaliy_Danmer написав:

Цікаво, що краще: string_view чи розумний вказівник на string?
За умови, що створюються лише для читання.
Чи є між ними різниця в сенсі швидкості та використання пам'яті?

Ви намагаєтесь порівняти різні речі. Використання розумних вказівників в цілому та string_view - ніяк не перетинається.

Ви схоже не зовсім розумієте, що то є таке той string_view, бо ви постійно його якось намагаєтесь пов'язати з string. Але string_view нічого не знає про string. Це не "обгортка" навколо string. Він навіть не підозрює, що string існує як тип; перетворення з string на string_view відбувається в межах string. string_view не пов’язаний із string і не покладається на нього.

Насправді це і є вся мета string_view: мати можливість містити незмінно рядок (набір символів) певного розміру, не знаючи, яким чином першочергово той рядок було алоковано чи взагалі як менеджиться. Те, що він може посилатися на будь-який тип рядка, який зберігає свої символи безперервно і є його суть.

Щодо швидкості та використання пам'яті теж недоречно порівнювати, в одних випадках string_view буде швидше у всіх сенсах, оскільки він дуже легкий, а в інших повністю програватиме string, бо вони не є взаємозамінні. І вам просто не вдасться замінити string на string_view, бо швидше за все ви зловите UB і тут вже й не може бути мови про якісь заміри швидкодії.

Лише для RO доступу string_view можна використати, зрештою для цього він і існує. І в більшості випадків він буде ефективніше за string const&. Але тут тре бути обережним і правильно його застосовувати, інакше простіше не заморочуватись з ним.

Подякували: Teg Miles, koala, leofun013

4

Re: string_view чи розумний вказівник на string

wander написав:
Vitaliy_Danmer написав:

Цікаво, що краще: string_view чи розумний вказівник на string?
За умови, що створюються лише для читання.
Чи є між ними різниця в сенсі швидкості та використання пам'яті?

Ви намагаєтесь порівняти різні речі. Використання розумних вказівників в цілому та string_view - ніяк не перетинається.

Ви схоже не зовсім розумієте, що то є таке той string_view, бо ви постійно його якось намагаєтесь пов'язати з string. Але string_view нічого не знає про string. Це не "обгортка" навколо string. Він навіть не підозрює, що string існує як тип; перетворення з string на string_view відбувається в межах string. string_view не пов’язаний із string і не покладається на нього.

Насправді це і є вся мета string_view: мати можливість містити незмінно рядок (набір символів) певного розміру, не знаючи, яким чином першочергово той рядок було алоковано чи взагалі як менеджиться. Те, що він може посилатися на будь-який тип рядка, який зберігає свої символи безперервно і є його суть.

Щодо швидкості та використання пам'яті теж недоречно порівнювати, в одних випадках string_view буде швидше у всіх сенсах, оскільки він дуже легкий, а в інших повністю програватиме string, бо вони не є взаємозамінні. І вам просто не вдасться замінити string на string_view, бо швидше за все ви зловите UB і тут вже й не може бути мови про якісь заміри швидкодії.

Лише для RO доступу string_view можна використати, зрештою для цього він і існує. І в більшості випадків він буде ефективніше за string const&. Але тут тре бути обережним і правильно його застосовувати, інакше простіше не заморочуватись з ним.

Можете навести кілька прикладів правильного і неправильного застосування?

5

Re: string_view чи розумний вказівник на string

Vitaliy_Danmer написав:

Можете навести кілька прикладів правильного і неправильного застосування?

Можу сформулювати так:

  • Ваша функція (інтерфейс), яка приймає значення, має мати права власності (ownership) на std::string? Якщо так, використовуйте std::string (non-const, non-ref). В такому випадку ви зможете явно перемістити (move) значення, якщо ви знаєте, що воно більше ніколи не використовуватиметься в контексті виклику;

  • Ваша функція (інтерфейс) лише читає рядок? Якщо так, використовуйте std::string_view (can be const, non-ref). В такому випадку ви зможете легко обробляти std::string чи char* без проблем і без копіювання. Це має замінити всі параметри std::string const&, але не забувайте слідкувати за lifetime'ом ваших буферів* (рядків);

  • Перед тим як змінювати ваш інтерфейс з std::string -> std::string_view пам'ятайте, що std::string гарантовано буде null-terminated, std::string_view – ні.

* Сприймайте std::string_view – як деяку форму константного посилання на буфер, що містить символи. Цим буфером може виступати, наприклад, std::string або масив char'ів тощо. І як наслідок, використання std::string_view не повинно продовжуватись за межами життя цього буфера.

Подякували: Teg Miles, leofun012

6

Re: string_view чи розумний вказівник на string

wander написав:
Vitaliy_Danmer написав:

Можете навести кілька прикладів правильного і неправильного застосування?

Можу сформулювати так:

  • Ваша функція (інтерфейс), яка приймає значення, має мати права власності (ownership) на std::string? Якщо так, використовуйте std::string (non-const, non-ref). В такому випадку ви зможете явно перемістити (move) значення, якщо ви знаєте, що воно більше ніколи не використовуватиметься в контексті виклику;

  • Ваша функція (інтерфейс) лише читає рядок? Якщо так, використовуйте std::string_view (can be const, non-ref). В такому випадку ви зможете легко обробляти std::string чи char* без проблем і без копіювання. Це має замінити всі параметри std::string const&, але не забувайте слідкувати за lifetime'ом ваших буферів* (рядків);

  • Перед тим як змінювати ваш інтерфейс з std::string -> std::string_view пам'ятайте, що std::string гарантовано буде null-terminated, std::string_view – ні.

* Сприймайте std::string_view – як деяку форму константного посилання на буфер, що містить символи. Цим буфером може виступати, наприклад, std::string або масив char'ів тощо. І як наслідок, використання std::string_view не повинно продовжуватись за межами життя цього буфера.

Тобто використати string_view для аргументу функції, який лише всередині неї використовується, — це правильне застосування.
Наприклад, передати ім'я та шлях до файлу, який відкривається в окремій функції.
Але не варто використовувати в контейнерах, якщо вони використовуються в різних функціях.
Наприклад, контейнер map, що є змінною класу й використовується в різних частинах програми.
Я правильно зрозумів?

7

Re: string_view чи розумний вказівник на string

Все трохи простіше, доки ви слідкуєте за lifetime'ом ваших рядків на які посилається string_view – все буде ОК. Обмеження майже ті ж, що й у випадку з char const*.