Re[8]: минусы STL
От: gid_vvp  
Дата: 20.02.07 06:19
Оценка:
Здравствуйте, Erop, Вы писали:

E>Здравствуйте, gid_vvp, Вы писали:


_>>пишем C++ обёртки над этим C style API

E>Ну это и есть так называемое "совсем не уменьшается производительность труда" и "зачем писать свой велосипед, если есть STL"

E>Но это всё лирика. Вот есть LISTBOX. Наверное он довольно известен. На всяк случай скажу, что там на элемент можно задать 32 бита данных.

E>И что же мы пишем, чтобы запихнуть туда итератор?

Ну итератор туда запихивать не стоит... он может инвалидироаться в самый неподходящий момент, лучше там хранить ID из map или hashmap
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[3]: Проблемы STL-контейнеров
От: Programador  
Дата: 20.02.07 09:40
Оценка:
Здравствуйте, Андрей Тарасевич, Вы писали:

АТ>Реальный способ тут только один — уситься пользоваться беззнаковыми типами как можно раньше. 99% целых типов в профессионально написаной среднестатистической программе должны являться беззнаковыми. Знаковые типы используются только в исключительных случаях.


Да ну — а java? Зачем они вообще беззнаковые? К томуже С никак не контролирует их. Пытался напмсать тут кое что на чистом С, потом плюнул и заменил одной командой __asm JC — даже не помню какие там типы были, рояли не играло
Re[4]: Проблемы STL-контейнеров
От: Programador  
Дата: 20.02.07 09:42
Оценка:
Ну кроме char конечно
Re[9]: минусы STL
От: x-code  
Дата: 20.02.07 13:47
Оценка: +1
Здравствуйте, gid_vvp, Вы писали:

E>>Но это всё лирика. Вот есть LISTBOX. Наверное он довольно известен. На всяк случай скажу, что там на элемент можно задать 32 бита данных.

E>>И что же мы пишем, чтобы запихнуть туда итератор?

_>Ну итератор туда запихивать не стоит... он может инвалидироаться в самый неподходящий момент, лучше там хранить ID из map или hashmap


О! Теперь я знаю, почему вычислительная мощность компьютеров растет, а скорость программ падает!

Мне еще где-то здесь предлагали создать объект с помощью new, поместить туда итератор,указатель на созданный объект запихнуть в DATA, а при уничтожении Listbox'a проходить по всем элементам и удалять память из под итераторов.

Мое ИМХО: ООП это отличная парадигма, существенно продвинувшая программирование, но это не значит что все переменные в программе должны быть активными объектами. Программа превращается в разбегающийся в разные стороны муравейник.
Объектами стоит делать то, что действительно является объектами в предметной области, или то что является объектом в системе, например объекты GUI.
Окно, кнопка — безусловно объект. Структуры данных (контейнеры) список, дерево, таблица — однозначно объекты. Но зачем делать объектом маленький итератор? Не перебор ли это?
Другими словами: объектом может быть то что самодостаточно. Контейнеру никто не нужен для существования. Итератору нужен контейнер — без него итератор бессмысленен, следовательно он лишь часть, примочка к контейнеру, а не самостоятельный объект. В этом смысле STL — что-то вроде кривой попытки заменить сишные указатели. Я вообще считаю перегрузку операций (в особенности операций доступа * ->) не очень хорошей вещью и делаю только перегрузку копирования (конструктор копирования и оператор присваивания) да и то по необходимости.
Re[14]: Размер stack-а главного thread-а
От: Erop Россия  
Дата: 20.02.07 15:26
Оценка:
Здравствуйте, Пётр Седов, Вы писали:

E>>Странно. В известных мне операционках, обычно можно отматать столько стэка, сколько надо...

E>>Пишешь нужное число в заголовок exeшника и всё...
ПС>Зачем patch-ить exe-файл? Серьёзный компилятор позволяет указать размер stack-а главного thread-а.

Конечно то, что ты пишешь, правда, но я и не предлагал патчить заголовок из hexeditor
Вот, скажем, если ты хочешь сделать приложение консольным, ты тоже будешь думать, что надо экзешник патчить, а не опцию линкера менять?
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[2]: Точки над i
От: Шахтер Интернет  
Дата: 20.02.07 16:14
Оценка: +1 -2
Здравствуйте, Smal, Вы писали:

S>Здравствуйте, all.


S>Долго пытался не влезать в эту дискуссию, но все же попытаюсь изложить собственное мнение. <...>


Не стоит вместо аргументов чем хороша STL заявлять, что те кто её критикует или не разобрались, или слишком консервативны и.т.п.

S>В действительности, даже такие структуры как std::map<string> достаточно быстры,


"За такие структуры у нас увольняют." (c) мой

S>Остается только надеяться, что такое положение дел положительно скажется на развитии стандартной библиотеки.


Она давно уже не развивается. Фактически, с её первого появления не была проделана необходимая работа над ошибками.
По сути STL как проект мертва.
В XXI век с CCore.
Копай Нео, копай -- летать научишься. © Matrix. Парадоксы
Re[14]: Reserve
От: Пётр Седов Россия  
Дата: 20.02.07 17:27
Оценка: +1
Здравствуйте, ., Вы писали:
>> Пишешь нужное число в заголовок exeшника и всё...
.>Ну это аналогично вызову reserve с большим числом прозапас (или специальному аллокатору с фиксированным размером).
Аналогия – вещь скользкая. И там, и там слово «reserve», но есть разница.
VirtualAlloc(NULL, 1024 * 1024, MEM_RESERVE, PAGE_READWRITE) резервирует диапазон виртуальных адресов. Поначалу эти виртуальные адреса не подкреплены физической памятью (физическая память – это оперативная память или swap file). Только по мере того, как stack растёт вглубь, виртуальные страницы отображаются на физические страницы (страница (page) – кусок памяти размером 4 KB). Поэтому в stack-е количество «лишней» физической памяти <= 4 KB. Выход за рамки резерва смертелен: возбуждается структурное исключение Win32 и программа, скорее всего, аварийно завершается.
vector<byte>::reserve(1024 * 1024) (и string::reserve(1024 * 1024)) запрашивает мегабайт физической памяти. Если используется малая доля резерва, то будет много «лишней» физической памяти (которая недоступна остальным процессам). Выход за рамки резерва влечёт realloc + переезд элементов на новое место жительства.
Пётр Седов (ушёл с RSDN)
Re[12]: минусы STL
От: LuciferMoscow Россия  
Дата: 20.02.07 17:54
Оценка:
Здравствуйте, gid_vvp, Вы писали:

E>>>Там идея такая, что можно преобразовывать строки в числа и взад. Довольно легко и прямо.

LM>>boost::lexical_cast
E>>>При этом они там строки короче чего-то вообще не аллокируют никогда.
LM>>MS реализация std::string
_>т.е. ты видел это ? (PowerPlant)
Нет, я видел boost::lexical_cast и MS реализация std::string
... << RSDN@Home 1.1.4 beta 4 rev. 358>>
Re[13]: минусы STL
От: gid_vvp  
Дата: 21.02.07 06:05
Оценка:
_>>т.е. ты видел это ? (PowerPlant)
LM>Нет, я видел boost::lexical_cast и MS реализация std::string

Боюсь этого не достаточно чтобы сравнивать
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[10]: минусы STL
От: gid_vvp  
Дата: 21.02.07 06:05
Оценка:
Здравствуйте, x-code, Вы писали:

XC>Здравствуйте, gid_vvp, Вы писали:


E>>>Но это всё лирика. Вот есть LISTBOX. Наверное он довольно известен. На всяк случай скажу, что там на элемент можно задать 32 бита данных.

E>>>И что же мы пишем, чтобы запихнуть туда итератор?

_>>Ну итератор туда запихивать не стоит... он может инвалидироаться в самый неподходящий момент, лучше там хранить ID из map или hashmap


XC>О! Теперь я знаю, почему вычислительная мощность компьютеров растет, а скорость программ падает!


Произведи замеры производительности и тогда говори о скорости.
Это во первых, во вторых мешать UI и логику очень плохая идея, ну не должны гуишные элементы содержать в себе логику.

XC>Мне еще где-то здесь предлагали создать объект с помощью new, поместить туда итератор,указатель на созданный объект запихнуть в DATA, а при уничтожении Listbox'a проходить по всем элементам и удалять память из под итераторов.


XC>Мое ИМХО: ООП это отличная парадигма, существенно продвинувшая программирование, но это не значит что все переменные в программе должны быть активными объектами. Программа превращается в разбегающийся в разные стороны муравейник.

XC>Объектами стоит делать то, что действительно является объектами в предметной области, или то что является объектом в системе, например объекты GUI.
XC>Окно, кнопка — безусловно объект. Структуры данных (контейнеры) список, дерево, таблица — однозначно объекты. Но зачем делать объектом маленький итератор? Не перебор ли это?
XC>Другими словами: объектом может быть то что самодостаточно. Контейнеру никто не нужен для существования. Итератору нужен контейнер — без него итератор бессмысленен, следовательно он лишь часть, примочка к контейнеру, а не самостоятельный объект. В этом смысле STL — что-то вроде кривой попытки заменить сишные указатели. Я вообще считаю перегрузку операций (в особенности операций доступа * ->) не очень хорошей вещью и делаю только перегрузку копирования (конструктор копирования и оператор присваивания) да и то по необходимости.

Это ты кому отвечаешь? Тем кто рекомендовал создавать итераторы на куче?
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[3]: Проблемы STL-контейнеров
От: Шахтер Интернет  
Дата: 21.02.07 08:15
Оценка: 1 (1) +2
Здравствуйте, Андрей Тарасевич, Вы писали:

АТ>Здравствуйте, Аноним, Вы писали:


А>>2. Все STL-контейнеры неявно копируются. Опасно, если неявная операция дорога.


АТ>Это опасность "по невнимательности". Таких опасностей в С++ много и недостаками они в рамках идеологии С++ считаются не должны.


Тут вопрос глубже на самом деле. А зачем вообще копировать контейнеры? Это требуется весьма нечасто. Соотвественно, ничего страшного нет в запрете на копирование и использовании специального метода clone для создание копии.

Копирование стандартных контейнеров разрешено на самом деле потому, что иначе их нельзя было бы хранить в контейнерах.
Иными словами один фундаментальный дефект STL -- неспособность контейнеров хранить некопирабельные типы приводит к другому -- разрешению неявного копирования контейнеров.

АТ>Реальный способ тут только один — уситься пользоваться беззнаковыми типами как можно раньше. 99% целых типов в профессионально написаной среднестатистической программе должны являться беззнаковыми. Знаковые типы используются только в исключительных случаях.


По моему, это слишком сильное утверждение.


struct Point
 {
  int x,y; // здесь вряд ли беззнаковый тип уместен
 };
В XXI век с CCore.
Копай Нео, копай -- летать научишься. © Matrix. Парадоксы
Re[3]: О дивный, идеальный мир С++ и STL!
От: Erop Россия  
Дата: 21.02.07 14:59
Оценка: -1
Здравствуйте, Андрей Тарасевич, Вы писали:

АТ>Это опасность "по невнимательности". Таких опасностей в С++ много и недостаками они в рамках идеологии С++ считаются не должны.

АТ>Ошибки при использовании беззнаковых типов (в т.ч. в примерах ниже) обусловлены обычно 1) невнимательностью и 2) неоправданным смешением знаковых и беззнаковых типов. По этой причине, аргументами их считать сложно.
АТ>Реальный способ тут только один — учиться пользоваться беззнаковыми типами как можно раньше.
АТ>"Страховочное" использование знаковых типов допустимо для начинающего программиста, но не более.

Это первая группа комментов. Если коротко, то так: "Увольте всех невнимательных программистов и напишите, наконец, прекрасную программу "Hellow World!" в одинчку. Внимательно, правильно и без этих всех глупых и труднообнаружимых ошибок!
Так?
Интересно, как ты относишься к private членам классов? Они ведь тоже с невнимательностью борятся. Просто надо писать и внимательно нтарии и не вызывать что попало где не надо



АТ>Слабый и странный "минус".
АТ>Неочевидно. Если и минус, то очень слабый.
АТ>По-моему это вопрос качества реализации. Нет?
АТ>Нет. Не вижу в этом минуса. А придумать ситуацию, когда это неудобно можно всегда.
АТ>В общес случае — нельзя. Но это ограничение имеет свои оправдания, свои плюсы и минусы. Странно видеть его в качестве "минуса".

Вторая большая группа "возражений". В переводе на русский: "Я не понял или не знаю что сказать"
Особенно прикольно последнее "возрадение". Интересно бы узнать плюсы такого ограничения, например


На этом я хотел уже закончить, но таки не могу НУ КАК МОЖНО ТАК ДУМАТЬ?

АТ>...Использование беззнакого типа вполне оправдано, ибо соответствует он заведомо неотрицательному значению. В данном случае наблюдается следование правилу "всегда использовать в программе только беззнаковые типы, кроме тех мест, где необходим знаковый тип", что более чем похвально.

Конечно более чем похвально. Так как повышает зарплаты тех, кто так делает, в виду малого их числа
А что делать с криворукими сотрудниками, которые так не делают надо смотреть чуть выше в этом посте, Да?

АТ>99% целых типов в профессионально написаной среднестатистической программе должны являться беззнаковыми. Знаковые типы используются только в исключительных случаях.


А вот это совсем интересно. Всё-таки чем так сильно C++ отличается от остальных процедурных и ООП языков? Почему-то в остальных вполне получается писать хорошие программы вообще без использования беззнаковых целых, и только на C++ 99% должны быть беззнаковыми?

Ещё интересно, как ты обходишься без типа unsigned double. Тяжело наверное?..



Выводы:
А выводы-то всё те же. Что мы видим с вами?
А вилим мы то, что STL очень заточен под идеологически правильные споры, под написание сверхкорректного кода каких-то мифических прекрасных сэмплов, каким-то не менее мифическими сверхвысококвалифицированными, сверхвнимательными и сверхаккуратными программистами.
Либо для обучения этих спецов (конечно, ещё Суворов говаривал, что в учении должно быть тяжело

А для тех, кто хочет что-то такое программировать в практических целях, например, чтобы продать, STL не выгодный какой-то. Так как далёк он от практики. Вопросы, которые важны для кого-то, кто пишет программы на практике, не являются минусами или являются особенностями реализации (ну вот есть у тебя такая особенность. А делать-то чего? , как будто реализация не может угробить и прекрасную идею ), операции со строками не важны, важно, чтобы можно было родить строку из любых объектов. Напрмиер из умныз указателей на открытые файлы, скажем, ну и так далее и тому подобное
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[2]: Версия MFC
От: Пётр Седов Россия  
Дата: 21.02.07 17:34
Оценка:
Здравствуйте, Аноним, Вы писали:
А>… MFC 4.2
Я ошибся. На самом деле вместе с MSVC6 поставляется MFC 6.0 (хотя файл называется mfc42.dll + варианты). Во-первых, это написано в MSDN (здесь):

ATL and MFC Version Numbers

The versions of MFC shipped with Visual C++ as listed in the following table.

MFC versionVisual C++ version
1.0Microsoft C/C++ 7.0
2.0Visual C++ 1.0
2.5Visual C++ 1.5
3.0Visual C++ 2.0
3.1Visual C++ 2.1
3.2Visual C++ 2.2
4.0Visual C++ 4.0
4.1Visual C++ 4.1
4.2Visual C++ 4.2
4.21 (mfc42.dll)Visual C++ 5.0
6.0 (mfc42.dll)Visual C++ 6.0
7.0 (mfc70.dll)Visual C++ .NET 2002
7.1 (mfc71.dll)Visual C++ .NET 2003
8.0 (mfc80.dll)Visual C++ 2005

Во-вторых, это написано в afxver_.h:

#define _MFC_VER 0x0600 // Microsoft Foundation Classes version 6.00, VC++ 6.0

Поэтому вместо «MFC 4.2» надо читать «MFC 6.0».
Извините, ввёл в заблуждение.
Пётр Седов (ушёл с RSDN)
Re[3]: Точки над i
От: Tom Россия http://www.RSDN.ru
Дата: 21.02.07 19:36
Оценка:
S>>В действительности, даже такие структуры как std::map<string> достаточно быстры,
Ш>"За такие структуры у нас увольняют." (c) мой
А можно по подробнее?
... << RSDN@Home 1.1.4 beta 4 rev. 303>>
Народная мудрось
всем все никому ничего(с).
Re[5]: Возвращаясь к украинской теме: Сколько же точек над i
От: jazzer Россия Skype: enerjazzer
Дата: 22.02.07 05:17
Оценка:
Здравствуйте, Programador, Вы писали:

(skipped)

Это к чему было? Ты, часом, веткой не ошибся?
jazzer (Skype: enerjazzer) Ночная тема для RSDN
Автор: jazzer
Дата: 26.11.09

You will always get what you always got
  If you always do  what you always did
Re[10]: минусы STL
От: dr.Chaos Россия Украшения HandMade
Дата: 22.02.07 11:03
Оценка:
Здравствуйте, x-code, Вы писали:

XC>Здравствуйте, gid_vvp, Вы писали:


E>>>Но это всё лирика. Вот есть LISTBOX. Наверное он довольно известен. На всяк случай скажу, что там на элемент можно задать 32 бита данных.

E>>>И что же мы пишем, чтобы запихнуть туда итератор?

_>>Ну итератор туда запихивать не стоит... он может инвалидироаться в самый неподходящий момент, лучше там хранить ID из map или hashmap


XC>О! Теперь я знаю, почему вычислительная мощность компьютеров растет, а скорость программ падает!


XC>Мне еще где-то здесь предлагали создать объект с помощью new, поместить туда итератор,указатель на созданный объект запихнуть в DATA, а при уничтожении Listbox'a проходить по всем элементам и удалять память из под итераторов.


А что программирование на ГУИ заканчивается? Тут вообще лучше не С++ использовать, но раз уж пришлось, то используй то средство, что подходит лучше в чем проблема? СТЛ от этого хуже на стала.

XC>Мое ИМХО: ООП это отличная парадигма, существенно продвинувшая программирование, но это не значит что все переменные в программе должны быть активными объектами. Программа превращается в разбегающийся в разные стороны муравейник.

XC>Объектами стоит делать то, что действительно является объектами в предметной области, или то что является объектом в системе, например объекты GUI.
XC>Окно, кнопка — безусловно объект. Структуры данных (контейнеры) список, дерево, таблица — однозначно объекты. Но зачем делать объектом маленький итератор? Не перебор ли это?
XC>Другими словами: объектом может быть то что самодостаточно. Контейнеру никто не нужен для существования. Итератору нужен контейнер — без него итератор бессмысленен, следовательно он лишь часть, примочка к контейнеру, а не самостоятельный объект. В этом смысле STL — что-то вроде кривой попытки заменить сишные указатели. Я вообще считаю перегрузку операций (в особенности операций доступа * ->) не очень хорошей вещью и делаю только перегрузку копирования (конструктор копирования и оператор присваивания) да и то по необходимости.

Вообще это все слой абстракции м-ду программистом и низкоуровневыми средствами (голые указатели, управление памятью). Не забываем, что С++ имеет совместимость с С. А в чем кривость этой попытки? Итератор — это тот же указатель по смыслу, только ограничен семантикой перебора, разыменования. Умный указатель это новая семантика которую уже внес С++ — семантика владения. ИМХО очень даже хорошо, что они разделены.

ЗЫ Кстати wxWidgets хотя и одна из самых древних ГУИ библиотек, гораздо более совместима с СТЛ, чем тот же МФЦ, правда МФЦ уже никто не развивает, что не может не радовать .
Побеждающий других — силен,
Побеждающий себя — Могущественен.
Лао Цзы
Re[4]: Точки над i
От: Шахтер Интернет  
Дата: 23.02.07 09:54
Оценка: +1
Здравствуйте, Tom, Вы писали:

S>>>В действительности, даже такие структуры как std::map<string> достаточно быстры,

Ш>>"За такие структуры у нас увольняют." (c) мой
Tom>А можно по подробнее?

Для хранения строк обычно используют всё-таки хеш таблицы, а не деревья.
Кроме того, string может иметь дорогой оператор копирования. Именно поэтому его нельзя использовать для работы с большим массивом строк.
Плюс фрагментация памяти.
В XXI век с CCore.
Копай Нео, копай -- летать научишься. © Matrix. Парадоксы
Re[5]: Точки над i
От: . Великобритания  
Дата: 23.02.07 11:16
Оценка: :)
Шахтер wrote:

> Для хранения строк обычно используют всё-таки хеш таблицы, а не деревья.

Просто hash_map нестандарна...

> Кроме того, string может иметь дорогой оператор копирования. Именно

> поэтому его нельзя использовать для работы с большим массивом строк.
> Плюс фрагментация памяти.
Тут же string в качестве ключа используется, копирование при помещении в map всё равно будет. Какая разница?
Разница только в алгоритме поиска по ключу — пополамным делением отсортированной структуры или через вычисление хеша и
поиска по хешу.
Со строками до нескольких килобайт думаю большой разницы не будет. memcmp работает очень быстро.
Posted via RSDN NNTP Server 2.0
но это не зря, хотя, может быть, невзначай
гÅрмония мира не знает границ — сейчас мы будем пить чай
Re[3]: Проблемы STL-контейнеров
От: Пётр Седов Россия  
Дата: 23.02.07 13:09
Оценка:
Здравствуйте, Андрей Тарасевич, Вы писали:

А>>2. Все STL-контейнеры неявно копируются. Опасно, если неявная операция дорога.

АТ>Это опасность "по невнимательности". Таких опасностей в С++ много и недостаками они в рамках идеологии С++ считаются не должны.
«Недостаток» – жёсткое слово. Я бы сказал мягче: спорный вопрос. Для string-а неявное копирование желательно, так же как неявное преобразование строкового литерала в string.

А>>4. STL-контейнеры провоцируют использование size_t. Беззнаковость этого типа влечёт проблемы.

АТ>Это неверно. В STL-контейнерах никак не используется 'size_t'. Используется же там контейнерно-зависимый беззнаковый тип 'size_type'.
Реализации STL, которые я видел, по умолчанию используют именно size_t.

АТ>Использование беззнакого типа вполне оправдано, ибо соответствует он заведомо неотрицательному значению.

Забавно читать следующий код:
Вместо «заведомо неотрицательного» string::npos можно было придумать что-нибудь вроде Boost.Optional, но «-1» проще.

АТ>В данном случае наблюдается следование правилу "всегда использовать в программе только беззнаковые типы, кроме тех мест, где необходим знаковый тип", что более чем похвально.

АТ>Ошибки при использовании беззнаковых типов (в т.ч. в примерах ниже) обусловлены обычно 1) невнимательностью и 2) неоправданным смешением знаковых и беззнаковых типов. По этой причине, аргументами их считать сложно.
А>>Сам он всячески призывает программиста использовать int.
АТ>В этом Страуструп не столько "не прав", сколько допускает черезмерное упрощение, ориентируясь на начинающего программиста (его книга изобилует такими упрощениями). Это лишь вопрос подходов к обучению: учиться ли правильному использованию беззнаковых типов с самого начала, или все таки отложить на потом. Страуструп считает, что лучше отложить. Многие считают что лучше сразу.
Беззнаковые типы и беззнаковая арифметика – разные вещи. Беззнаковая арифметика (особенно беззнаковое вычитание) – низкоуровневая техника и грабли. Её стоит использовать только в исключительных случаях. Подробнее: беззнаковый спор
Автор:
Дата: 12.11.06
.

А>>Какое отношение size_t имеет к array-based контейнерам (vector, string), ещё понятно: в языках C/C++ длина/индекс массива выражаются типом size_t. Какое отношение size_t имеет к node-based контейнерам (list, map), непонятно совсем. В 90-ые годы (время проектирования STL), когда ещё живы были 16-битные платформы, использование size_t было оправдано. Сейчас это источник тонких ошибок.

АТ>Это утверждение построено на неверном предположении, что используется именно тип 'size_t'. На самом деле же никакого 'size_t' там и близко нет. Не надо путать 'size_t' с 'container<>::size_type'.
Реализации STL, которые я видел, по умолчанию используют именно size_t. Смотрите выше.

А>>"Проблему size_t" можно решить несколькими способами:

АТ>Реальный способ тут только один — уситься пользоваться беззнаковыми типами как можно раньше. 99% целых типов в профессионально написаной среднестатистической программе должны являться беззнаковыми. Знаковые типы используются только в исключительных случаях.
АТ>"Страховочное" использование знаковых типов допустимо для начинающего программиста, но не более.
Про беззнаковую арифметику смотрите выше.

А>>5. Нельзя получить итератор по указателю на элемент контейнера за константное время.

АТ>В общес случае — нельзя.
Да, я писал об этом здесь
Автор: Пётр Седов
Дата: 15.09.06
:

A_A>А кто сказал, что это возможно для любых итераторов и любых контейнеров?
Никто. Но для некоторых возможно:


АТ>Но это ограничение имеет свои оправдания, свои плюсы и минусы. Странно видеть его в качестве "минуса".

Вполне возможен такой вариант. Все контейнеры имеют метод iterator_from_pointer. В некоторых случаях iterator_from_pointer работает за константное время (например, list::iterator_from_pointer в Release-конфигурации). В некоторых случаях iterator_from_pointer работает за время O(container.size()) (например, deque::iterator_from_pointer, list::iterator_from_pointer в Debug-конфигурации).
MaximE пишет об этом здесь
Автор: MaximE
Дата: 19.08.06
(он назвал «derive_iterator»).

А>>6. Вместо метода empty удобнее был бы метод с позитивным смыслом, например has_elems (возвращает true <=> в контейнере есть хотя бы один элемент).

АТ>Неочевидно. Если и минус, то очень слабый.
Чем меньше отрицаний, тем понятнее код. Например, вместо:
while (!Queue.empty())
{
  ...
}

было бы лучше писать:
while (Queue.has_elems())
{
  ...
}

Чтобы писать понятный код, нужны методы has_elems и is_empty (например, «assert(Queue.is_empty())»).
Функции вроде char_traits::not_eof производят странное впечатление.

А>>7. Нельзя const_cast const_iterator в iterator. Я с этой проблемой на практике не сталкивался. Теоретически, может возникнуть при неудачном дизайне.

АТ>Слабый и странный "минус".
Иногда нужно снять константность с итератора. Скотт Мейерс в книге «Эффективное использование STL»
Автор(ы): Скотт Мейерс
В этой книге известный автор Скотт Мейерс
раскрывает секреты настоящих мастеров, позволяющие добиться максимальной
эффективности при работе с библиотекой STL. Во многих книгах описываются
возможности STL, но только в этой рассказано о том, как работать с этой
библиотекой. Каждый из 50 советов книги подкреплен анализом и убедительными
примерами, поэтому читатель не только узнает, как решать ту или иную задачу, но
и когда следует выбирать то или иное решение — и почему именно такое.
пишет (совет 27): «Используйте distance и advance для преобразования const_iterator в iterator». Это криво и долго.

А>>9. list

А>>9.1. list спроектирован так, что либо size за константное время, либо splice (вариант с 4-мя параметрами) за константное время (при условии, что allocator-ы равны).
АТ>А что делать? Так устроен мир. Именно к STL это мало относится.
Неудачный дизайн. Я бы добавил проблемному splice-у дополнительный параметр:
template<...>
class list
{
  ...
  int m_Size;
  ...
  int size() const
  {
    return m_Size;
  }
  ...
  void splice(iterator Pos, list& Source, iterator Begin, iterator End, int Len)
  {
    // Len - длина перетаскиваемой последовательности
    assert(Len == distance(Begin, End));
    if (m_Allocator == Source.m_Allocator)
    {
      // перетащить дёшево (shallow) за константное время
      ...
      m_Size += Len;
      Source.m_Size -= Len;
    }
    else
    {
      // перетащить дорого (deep) за время O(Len)
      ...
    }
  }
  ...
};

Кстати, эта тема регулярно появляется. Ещё одно обсуждение: std::list &mdash; size vs splice
Автор: programmater
Дата: 21.02.07
.

А>>10. string

А>>10.1. Если программа много работает с текстом, то string (или его аналог) — ходовой тип. При этом желательно, чтобы неявное копирование string-а было дешёвым. Для этого реализация string-а может использовать разделяемый (между несколькими string-ами) буфер с подсчётом ссылок. Но string спроектирован в mutable стиле, поэтому у него есть не-const методы begin, end, rbegin, rend, operator[] и at. Если реализация string-а считает ссылки, то эти методы делают copy-on-write (даже если вы не собираетесь ничего менять) и запрещают разделяемость буфера.
АТ>По-моему это вопрос качества реализации. Нет?
Неудачный дизайн влечёт корявую реализацию. Я бы сделал так:
template<typename TChar, ...>
class basic_string2
{
private:
  // структура переменной длины
  struct Data
  {
    int Refs;
  ...
    int Len;
  #if defined(_MULTI_THREAD) && defined(_DEBUG)
    // прописка; если равно 0 (по умолчанию), то строку можно использовать в любом thread-е
    DWORD HomeThreadId;
  #endif
    TChar Chars[1]; // (Len + 1) TChar-ов
  };
  Data* m_pData;
...
  void check_thread() const
  {
  #if defined(_MULTI_THREAD) && defined(_DEBUG)
    // проверить прописку
    assert((m_pData->HomeThreadId == 0) || (m_pData->HomeThreadId == GetCurrentThreadId()));
  #endif
  }
...
public:
...
  void restrict_to_cur_thread_only()
  {
  #if defined(_MULTI_THREAD) && defined(_DEBUG)
    assert(m_pData->HomeThreadId == 0);
    m_pData->HomeThreadId = GetCurrentThreadId();
  #endif
  }
...
  int len() const
  {
    check_thread();
    return m_pData->Len;
  }
...
  // прямой доступ к буферу на чтение
  const TChar* c_str() const
  {
    check_thread();
    return m_pData->Chars;
  }
...
  // неявное копирование дёшево
  basic_string2(const basic_string2& Source) { ... }
  basic_string2& operator=(const basic_string2& Source) { ... }
  // пример использования:
  //   string2 s = "abc";
  //   string2 t = s; // дешёвое копирование (shallow)
  //   assert(s.c_str() == t.c_str()); // общий буфер
...
  // дорогое копирование явно
  basic_string2 DeepCopy() const { ... }
  // пример использования:
  //   string2 s = "abc";
  //   string2 t = s.DeepCopy(); // дорогое копирование (deep)
  //   assert(s.c_str() != t.c_str()); // разные буферы
...
  TChar operator[](int Index) const
  {
    check_thread();
    assert((0 <= Index) && (Index <= m_pData->Len)); // можно читать завершающий '\0'
    return m_pData->Chars[Index];
  }
...
  // mutable-стиль, по желанию
  void set_at(int Index, TChar c)
  {
    check_thread();
    assert((0 <= Index) && (Index < m_pData->Len)); // нельзя писать в завершающий '\0'
    // copy-on-write
  ...
    m_pData->Chars[Index] = c;
  }
...
  // прямой доступ к буферу на запись
  TChar* lock(int Len)
  {
    check_thread();
    assert(Len > 0);
  ...
  }

  // аннулирует указатель, выданный lock-ом
  void unlock() { ... }
...
};

Почти все методы начинаются с check_thread. Это отладочная проверка: можно ли использовать строку в текущем thread-е. WinAPI-шная функция GetCurrentThreadId быстрая (Windows 2000 SP 3):

77E876A1   mov         eax,fs:[00000018]
77E876A7   mov         eax,dword ptr [eax+24h]
77E876AA   ret

поэтому check_thread должен работать быстро.

А>>10.2. Нет завершающего '\0'.

АТ>Нет. Не вижу в этом минуса. А придумать ситуацию, когда это неудобно можно всегда.
Абсурд в том, что обычно реализация std::string-а хранит завершающий ‘\0’ (чтобы иметь быстрый c_str), но официально доступ к нему запрещён. Теоретически, может быть реализация std::string-а с умным substr (исходная строка и подстрока разделяют общий буфер), но я такого не видел.
Пётр Седов (ушёл с RSDN)
Re[6]: Точки над i
От: Erop Россия  
Дата: 24.02.07 10:24
Оценка: -2
Здравствуйте, ., Вы писали:

>> Для хранения строк обычно используют всё-таки хеш таблицы, а не деревья.

.>Просто hash_map нестандарна...
Конечно это это плюс STL. Что же ещё?
Людям, как обычно нужно, не чтобы стандартно, а чтобы работалось и дёшево переносилось
Можно хоть свой собственный hash_map с собой таскать всегда


>> Кроме того, string может иметь дорогой оператор копирования. Именно

>> поэтому его нельзя использовать для работы с большим массивом строк.
>> Плюс фрагментация памяти.
.>Тут же string в качестве ключа используется, копирование при помещении в map всё равно будет. Какая разница?
Ну так в std::map<std::string> обычно есть где-то в недрах аналог std::vector<std::string>. а std::vector любит время от времени копировать свои потроха, при этом std::string обычно копируется задорого, да ещё и кучу фрагментирует как подорванное
.>Со строками до нескольких килобайт думаю большой разницы не будет. memcmp работает очень быстро.

Ну попробуй, например, родить hash_map и map для словника английского языка например.
Узнаешь много интересного
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.