LINUX.ORG.RU

C++ негодования тред - std::string

 , ,


0

2

Оно не умеет дешево создаться на основе существующего char* без копирования.

Писать свой класс строк как во время Сталина? Писать свой аллокатор в интересующей области памяти?

★★★★★

Последнее исправление: vertexua (всего исправлений: 4)

Ответ на: комментарий от vertexua

Без копирования - только пилить свое (пока). Вариантов - тысячи, некоторые уже предложили.

maverik ★★
()
Ответ на: комментарий от vertexua

А откуда у тебя большой char *? Используй сразу std::string. В Си-функции можно передавать &str[0] теперь безопасно. В C++11 std::string обязан хранить память линейно. В крайнем случае используй std::pair<std::unique_ptr<char[]>, size_t sz>.

Инициализироваться из char * без копирования - плохая идея для класса в духе std::string.

anonymous
()
Ответ на: комментарий от namezys

Как я понял, причина в итератора. Реализовать их сложнее?

А как ты это реализуешь? Там есть такое требование:

std::string test("test");
std::string zero_cost_copy(test); // Данные не дублируются (копируются), а разделяются с первой строкой.
auto iter = zero_cost_copy.begin(); // Сохраняем итератор.
zero_cost_copy[1] = 'o'; // WTF?
*iter; // БДЫЩ!
По стандарту после следующего вызова «zero_cost_copy[1] = 'o';» итераторы должны остаться валидными. Но тут у нас разделяемые данные, которые портить нельзя - надо копировать. В итоге мы или копируем и «нарушаем стандарт» или отказывается от COW.

DarkEld3r ★★★★★
()
Ответ на: комментарий от vertexua

А итератор взял и магически начал ссылаться на копию с изменениями

И тогда на лоре появится тема «хочу зеро-кост итераторы». Ну и подозреваю (искать лень), что текущий стандарт это запрещает тем или иным образом.

DarkEld3r ★★★★★
()

std::string уже давно умеет в CoW. Move-семантика, опять же. Ну, или шабонами, епта.

anonymous
()

const string&

QString

anonymous
()
Ответ на: комментарий от anonymous

В треде есть мнение что уже разумел ибо не по стандарту и стреляет в ногу

vertexua ★★★★★
() автор топика

Что пишешь хоть, что так принципиальна скорость копирования строки?

anonymous
()
Ответ на: комментарий от DarkEld3r

В итоге мы или копируем и «нарушаем стандарт» или отказывается от COW.

В итоге для этого итератор должен стать сложным и фактически хранить ссылку на std::string, и выполнять operator[]. Стоит ли оно того, не знаю.

namezys ★★★★
()
Ответ на: комментарий от anonymous

В Си-функции можно передавать &str[0] теперь безопасно. В C++11 std::string обязан хранить память линейно

технически, оно всегда и было безопасно. ты видел хоть одну версию STL, в которой был нелинейный буфер в std::string?

waker ★★★★★
()
Ответ на: комментарий от vertexua

Можно посмотреть на boost::interprocess::basic_string Или где он там. В общем, на бустовую реализацию строк в разделяемой памяти.

anonymous
()
Ответ на: комментарий от anonymous

да, про стандарт я знаю. но этот пункт стандарта игнорируют чуть более чем все. сомневаюсь, что есть хоть одна реальная программа на крестах, которая не лазит в строки таким способом.

waker ★★★★★
()
Ответ на: комментарий от vertexua

Я понял почему такая фича в std::string «не нужна»

И почему же? (я не троллю, правда интересно услышать соображения на тему, а тред читать лень)

DELIRIUM ☆☆☆☆☆
()
Ответ на: комментарий от waker

У нас говнокода в проекте полно, но чтобы в std::string лазили таким образом ни разу не видел. Как такое вообще может пройти ревью?

DELIRIUM ☆☆☆☆☆
()
Ответ на: комментарий от DELIRIUM

Как такое вообще может пройти ревью?

а какая объективная причина может помешать этому пройти ревью, кроме нарушения пункта стандарта, который не встречается в природе?

(тем более, что выше заметили, что в новом стандарте все чики-пуки)

waker ★★★★★
()
Последнее исправление: waker (всего исправлений: 1)
Ответ на: комментарий от DELIRIUM

Просто потому что string владеет буфером внутри и освобождает память потом.

Ну допустим мы введем галочку «dont_delete». Ок, хоть и уродство. А что будет когда мы будем записывать? COW? Хотел бы я посмотреть на лицо программиста, когда при изменении символа в строке приложение упадет по нехватке памяти.

Не делать COW и прописывать насквозь в изначальный буфер? Нужно будет поддерживать одновременно такие string_view, в которые read only и никогда не пишут, и такие какие могут. Слишком много вопросов. А сейчас например string фантастически дуракоустойчив

vertexua ★★★★★
() автор топика

код под NDA?

можешь потом показать готовый код класса для твоего велосипеда?

(чтобы мы его коллективно скопипастали)

stevejobs ★★★★☆
()
Ответ на: комментарий от stevejobs

Саму строку что-ли, или весь велик? Не, это домашняя штука, может когда-то и выброшу. Но реально проект учебный

vertexua ★★★★★
() автор топика
Ответ на: комментарий от vertexua

строку и пример использования. А то срач на две страницы, а что в конце получилось, чем сердце успокоилось - непонятно)

stevejobs ★★★★☆
()
Последнее исправление: stevejobs (всего исправлений: 1)
Ответ на: комментарий от stevejobs

Я ее в последнюю очередь буду пилить, почти все готовое напишу на обычных строках, а потом заменю в узких местах. Как там говорилось о преждевременной эякуляции? Premature optimization is a root of all evil

vertexua ★★★★★
() автор топика
Ответ на: комментарий от vertexua

Вообще-то: Premature ejaculation is a root of all evil.
Да и в целом такие треды показывают больше некомпетентность постующий, чем раскрывают истинные решения. Ви батенька-таки провокатор.

anonymous
()

Оно не умеет дешево создаться на основе существующего char* без копирования.

А что из std::string тебе нужно вызывать, что оно настолько кошерно и нет аналога для char*, что так обеспокоен стоимостью копирования?

nikitos ★★★
()
Ответ на: комментарий от vertexua

Ну допустим мы введем галочку «dont_delete». Ок, хоть и уродство. А что будет когда мы будем записывать? COW? Хотел бы я посмотреть на лицо программиста, когда при изменении символа в строке приложение упадет по нехватке памяти.

До недавнего времени std::string() поддерживал CoW опционально по стандарту и gcc даже его реализует. Запретили CoW только в c++11. Лишнее выделение памяти не аргумент для плюсовой программы, т.к. они могут случаться (и случаются на практике) постоянно явно или неявно.

mashina ★★★★★
()
Последнее исправление: mashina (всего исправлений: 1)
Ответ на: комментарий от Pavval

Я верю в разные теории заговора, чо не так? У меня к джобсу пометка стоит «шапка из фольги», особенно больше ничем не примечателен

vertexua ★★★★★
() автор топика
Ответ на: комментарий от mashina

Запретили CoW только в c++11. Лишнее выделение памяти не аргумент для плюсовой программы, т.к. они могут случаться (и случаются на практике) постоянно явно или неявно.

Здесь дело не в лишнем выделении памяти, хотя это тоже аргумент. Для контейнеров декларируются сложности алгоритмов и CoW их нарушает. К примеру operator[] должен отрабатывать за константное время O(1), в случае CoW он может привести к разделению памяти и сложность будет O(n). CoW пытается усидеть на всех стульях, и сохранить семантику и чтобы работало быстренько. Хорошо сделали, что запретили. Хотите CoW - сделайте себе typedef std::shared_ptr<std::string> MyCowString.

Dendy ★★★★★
()

Две копейки. Идея mmap текстового файла правильная. Претензии к std::string по поводу работы на существующем буфере справедливы. Задача решается реализацией аллокатора, который ничего не аллоцирует и не удаляет. Пользоваться после этого только константными строками.

Dendy ★★★★★
()
Ответ на: комментарий от Dendy

Правильный аргумент

typedef std::shared_ptr<std::string> MyCowString

А вот это толстота

vertexua ★★★★★
() автор топика
Ответ на: комментарий от Dendy

Задача решается реализацией аллокатора, который ничего не аллоцирует и не удаляет. Пользоваться после этого только константными строками.

Костыли. Реализация «StringRef» - единственное некостыльное решение.

Pavval ★★★★★
()
Ответ на: комментарий от Dendy

Для контейнеров декларируются сложности алгоритмов и CoW их нарушает. К примеру operator[] должен отрабатывать за константное время O(1), в случае CoW он может привести к разделению памяти и сложность будет O(n).

Ничего он не нарушает. В стандарте, где он разрешён, нет таких требований к оператору [] у строки. Чукчи не дураки. В общем, запретили это немного из других соображений, хотя связанных с [].

Хотите CoW - сделайте себе typedef std::shared_ptr<std::string> MyCowString.

Это же нифига не CoW

mashina ★★★★★
()
Ответ на: комментарий от vertexua

То, что ты хочешь, в С делается передачей в функцию указателя (на произвольное место в буфере), в С++ — итераторов.

staseg ★★★★★
()
Ответ на: комментарий от namezys

в общем случае вообще не обещает, что это будет непрерывный буфер.

В новом стандарте уже обещает для char и wchar_t

anonymous
()
Ответ на: комментарий от Dendy

А, ну да, точно. Что там у нас в C++11 за CoW smart pointer или самодельный писать?

Очевидно, ничего. Generic CoW сделать нельзя.

mashina ★★★★★
()
Ответ на: комментарий от vertexua

Тот который из LLVM? Почему ксати? Какие плюсы и минусы?

Нет, любой. В случае NIH - реализация от Bicycle Corp.

Pavval ★★★★★
()

Определенно, С++ это диверсия против здравого смысла.

2014 год, лор 2 дня мусолит как лучше сделать обертку над куском памяти.

Итераторы(!), буст(!), новый стандарт(!).

Да какой-нибудь сисадмин с месячными курсами по С, <string.h> и valgrind'ом наперевес уже решал бы задачу (а возможно уже бы и и решил) а не Проектировал Абстракции

Удачи ТСу, конечно

anonymous
()
Ответ на: комментарий от anonymous

Ты даже не понял, что обсуждается.

anonymous
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.