LINUX.ORG.RU

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

 , ,


0

2

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

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

★★★★★

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

Ответ на: комментарий от no-such-file

Обещаю не делать раз не надо. Но почему? Аллокатор то был бы фейковый, на конкретный кусок, конкретный указатель, а потом reserve

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

Напиши yet another string class с copy-on-write и поэтессами. Или посмотри в EASTL, там вроде было что-то.

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

Ну вот у меня есть много функций, которые берут строку, и что-то там с нее читают, парсят. const string& str конечно классно, но я собственно не хочу ее создавать копированием в принципе, так как у меня большой char*, от которого я хотел бы брать куски, завернутые в std::string с указанием начала и размера. Если бы std::string умела дешево оборачивать такие куски, была бы zero_copy_string, то было бы збс

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

Ха, напиши. Я то напишу (когда дело дойдет до оптимизаций). Пока бы хоть как-то написать. Дай пока поныть и посокрушаться.

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

Тебе фактически надо класс, которые ссылается на std::string, но меняет индексы?

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

Похожая штука есть в Qt: QString и QStringRef (если я правильно помню)

namezys ★★★★
()
Последнее исправление: namezys (всего исправлений: 1)

Оно не умеет дешево создаться

дешево

Как показывает практика дебагинх чаров со всякими str*() из string.h обходиться значительно дороже.

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

у меня большой char*, от которого я хотел бы брать куски, завернутые в std::string с указанием начала и размера. Если бы std::string умела дешево оборачивать такие куски

А зачем здесь вообще эта прослойка в виде string?

typedef std::pair<char*, int> zero_copy_string;

И дальше работаешь с памятью напрямик, как мужик.

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

Тебе фактически надо класс, которые ссылается на std::string, но меняет индексы?

Можно выразиться и так. Qt тащить не хотелось бы.

Я думаю что когда дело дойдет до оптимизаций, то буду пользоваться char* и size.

Дело в том, что это не совсем строки в обычном понимании, а просто буферы байтов, например в них может быть \0, во всяких функциях со строками С ожидаются null-terminated строки, что не подходит

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

А оно должно уметь? Не вижу в этом смысл.

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

но это если смотреть на код с т.з. эффективности.

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

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

А на фига тебе тогда этот гроб std::string тащить?

Тебе надо завладеть указателем фактически, и умения ссылаться на твой объект. Но правда я не очень представляю, как гарантировать, что ссылка валидна, дешево. Если только через copy-on-write или похожую стратегию, но это может быть избыточно.

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

А что и куда ты хочешь конкатенировать? Если кусок с зеро-копи к нормальной обычной строке с собственной памятью - определил std::string& operator += (std::string &s, const zero_copy_string &z) и дергай в нем s.append(...).

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

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

С чего это? Во первых, нет требований об уникальном буфере. а, во вторых, внутри объекта можно строить дерево для обхода, например, чтоб объектинять и изменять строки. Правда, в glibc++ не рализовано второе, а вот первое вроде сделали (хотя могу и ошибаться).

Да и что, у std::string нет аллакатора?

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

write нету. Это смонтированый через mmap read-only многогектарный файл

Значит у тебя абсолютно другая стратегия управления. Тут и указателя достаточно.

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

С чего это?

с того, что каждый раз, когда ты передашь в функцию, принимающую std::string, строку в виде «some text» - она неявно скопируется. еще можно ее скопировать явно, через std::string(«some text»). но не копировать - нельзя.

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

Тю, а всякие strcat потом юзать и прочую некошерность.
через mmap read-only многогектарный файл

Ты явно что-то делаешь не так.

nanoolinux ★★★★
()

пусть копируется, тебе жалко?

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

Строки клеить (к другим!), парсить, передавать туда-сюда хотелось бы через zero_copy_string какой-то самодельный, чтобы пока строка путешествует, она просто ссылалась на файл. А так хочу передать в парсер - так или char*/size или копируй в string.

Но главное что я теперь понял, что такой сценарий действительно не должен входить в std::string, так как она то не знает что underlying буфер - read only и более того, не нужно ним владеть. Это действительно задача более специализированной кастомной строки

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

Есть еще std::basic_string, там вроде можно попытаться поиграть со стратегией владения, точнее с аллакатором, чтоб он не копировать и не удалял. Но это может быть черевато.

namezys ★★★★
()

А унаследовать string и добавить ему свои функции можно? Там же все равно указатель на char внутри, он private или protected?

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

так как у меня большой char*, от которого я хотел бы брать куски, завернутые в std::string с указанием начала и размера.

Не понимаю, зачем вам для этого нужен std::string?
Свой класс с указателем на начало/конец char*. Но при изменении (добавление/удаление/замена/слияние) строки придется делать копирование.

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

Свой класс с указателем на начало/конец char*.

Нафига так дофига? Итераторы + стандартные алгоритмы - этого будет достаточно!

AF ★★★
()

я так и не понял, кто и зачем запретил тебе работать в C++ с сишными строками. Или уж давно бы написал свой класс, удовлетворяюший твои хотелки, но нет же, надо поныть на ЛОРе.

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

Нафига так дофига? Итераторы + стандартные алгоритмы - этого будет достаточно!

А чем итератор отличается от указателя? :)

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

Я пришел ИМЕННО поныть. Написать - каждый напишет.

Но кстати, 1) были в треде дельные советы 2) Я понял почему такая фича в std::string «не нужна»

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

Одно может абстрагировать другое

Значит смысл фразы

Нафига так дофига? Итераторы + стандартные алгоритмы - этого будет достаточно!

Можно понять так - «зачем так много, ведь можно еще больше».

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

А чем итератор отличается от указателя? :)

Слишком толсто :Р

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

Во первых, нет требований об уникальном буфере.

Неявный запрет на copy-on-write есть.

Вроде, в GCC на это забили, но есть ключ отключающий COW.

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

Если ты создаешь строку из другой строки, то это не обязательно происходит.

из [const] char * — обязательно.

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

Да, что-то похожее. Хотя не знаю стоит ли их тащить

В гцц 4.9 уже добавили, так что, возможно, тащить и не придётся:

An implementation of std::experimental::string_view.

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

решил строку использовать как нестроку? ССЗБ, страдай

stevejobs ★★★★☆
()

оффтопик: в гугле заставили штудировать кресты? или чувствуешь что «чего-то» не хватает?

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

Есть кресты в определённой мере, потому дома качаю мышцу. Раньше писал, даже на работе, на крестах. Но много времени ушло с тех пор, вот ковыряю заново, по-модному

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

у меня большой char*, от которого я хотел бы брать куски, завернутые в std::string с указанием начала и размера.

char *myLengthyString = ...;
std::string part(myLengthyString + 1337, 666); // 666 символов начиная с 1337-го. Не взлетит при использовании wchar ну и т.д.
maverik ★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.