Здравствуйте, Tonal-, Вы писали:
T>А в этом разрезе, отрицательные величины как-то странненько смотряться. T>Чем поведение контейнера при адресации [-10] должно отличаться от [4294967286]?
У индексов есть два момента.
1) нередко бывает так, что в процессе итерации удобно выходить за границу массива, что и показывает, что пора заканчивать итерацию
2) Бывает таки так, что индексы участвуют в вычислениях. Например часто хочется узнать какой из индексов больше и на сколько . Или храниить какие-то диапазоны индексов, которые легко могут выходить за область индексов массива.
T>>>И таки исходный вопрос: многие ли операции в ваших программах действительно требуют работы со знаковыми типами и итераций по ним? E>>Практически любое целое число в моих программах может оказаться отрицательным. T>Т.е. количество пользователей -5чел — вполне нормальная ситуация?
Если речь о пользователях STL -- то да . Например так "Итого: -5 пользователнй STL, за прошлый день"
T>Этот ассерт будет не более информативен, чем сравнение с UINT_MAX/2 для беззнаковых. T>А вот если в нём действительно будет проверяться допустимый ожидаемый диапазон...
А если качество не ограниченно сверху ничем разумным? Вот, скажем пример оценки качества (кода): "Ваша премия за след. квартал составит столько-то долларов"
E>>Ещё пример такого числа -- координаты точки (например на экране): x и y. E>>Вдруг я кусок окна задвину за границу экрана? T>Опять же, часто ли ты эти отрицательные координаты используються для индексации массива?
Ну экран запросто можно считать двумерным массивом пикселей (в приниципе он им и является).
И хотя реальных обращений к экрану, за его пределами не выполняется, тем н менее координаты окон на экране удобно иметь знаковыми, хотя и не все координаты "пикселей" в таких окнах будут валидными. Зато мы сможем оперировать с окнами, у которых на экране находится только часть...
E>>Ну и так дадее. Совершенно повсеместно. Специально для случая с индексом я приведу тебе один пример. А вообще-то был тут где-то недалеко здоровычй флейм про беззнаковые числа. Пиши туда? E>>
for( int i = myArr.Size() - 5; i >= 0; i -= step )
E>> sum += myArr[i];
T>Чуть длиннее: T>
if (myArr.Size() > 5)
T> accumulate(advance(myArr.rbegin(), 5), myArr.rend(); sum);
Э-э-э а где тут слово srep?
T>По моему, проблема тут таки не в STL, а в некотором смешении понятий: T>Целое число как абцисса и как индекс в массиве это совершенно разные типы. T>В первом случае знак вполне осмыслен, во втором нет.
А в чём разница?
T>Код с итераторами действительно становиться более безопасный в плане выхода за граници, как только это понимаешь.
Он не только более безопасный, но ещё и менее гибкий
А вообще-то я согласен, что вопрос о беззнаковых индексах и о итераторах связан, но не так прямо тут уже была больискошая дискуссия на эту тему
лучше флеймить там
E>>>> E>>Проблема в том, что то, что ты называешь С-with-classes не такой уж плохой язык. А шаблоны -- страшная всё-таки хреновина. Ну вот STL всё равно с нами. И всегда сложный. Даже если ты с шаблорнами пишешь, то всё равно он сожный T>Я не утверждаю что он плохой. T>Он несколько другой. T>Ну и код, с применением шаблонов часто получается компактнее и быстрее. T>Ну а понимание — дело наживное.
Проблемы с шаблонами у меня обычно не из-за понимания, во всяком случае у меня, а с другим. Два есть источника обычно. Один состоит в излишнем оптимизме многих наших разрабочиков, при оценке чвоих сил при написании шаблонов. А второй происходит при поддержке шаблонного кода. Просто шаблоны в C++ сделаны стрёмно. Они слишком гибкие, и их очень неудобно и невыразительно можно ограничивать в гибкости. Ну и нет нужных сервисов (скажем списков типов или полей), но, зато это всё можно реализовать через одно место
А что касается "более быстрого и компактного кода с шаблонами", то у меня есть такое вот наблюдение над задачами, которые реально возникают даже при разработке очень очень сложных и наукоёмких программ. Такие проблемы, ИМХО, хорошо решаются в следующем порядке
1) Если можно как-то просто и естественно сделать без виртуальных функций, то это решение оказывается самым хорошим, быстрым и поддерживаемым.
2) Если п. 1 не получился, а с виртуальными функциями, но без шаблонов, таки получается сделать как-то естественно и просто, то обычно это и есть хорошее решение.
3) Если и 1 и 2 не прошли, то значит задача реально небанальная. И, возможно, приминив шаблоны её удастся решить приемлемо неплохо.
При этом уровень подготовки спеца, который может хорошо решать задачи такой сложности растёт в этом списке довольно значительно...
T>Перенос сколько-нибудь сложного кода даже между разными компиляторами дело не лёгкое. T>И если для поддерживаемой платформы нет вменяимого компилятора, то даже идеальная стандартная библиотека не поможет... T>Другое дело, что собственный код в таком случае проще адаптируется.
Да. И даже если компилятор есть...
Я был удивлён в своё время, когда вдруг понял, что переносимость в смысле C++ имеет мало отношения к переносимости программ в утилитарном смысле. То есть как сделать так, чтобы программа, которая работала на одной платформе, заработала на другой
Но в любом случае флейм про signed\unsigned лучше продолжать тут :)
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Здравствуйте, CrazyClown, Вы писали:
E>>Типа обычно можно и проще. Занчит лучше делать таки проще
CC> Делать проще громоздкий синтаксис C++ не позволяет. Так что приходится делать так, как делает STL. CC> Конечно же, на каждый случай применения STL найдутся сотни частных случаев, когда можно сделать проще и тупее — ну так это беда любого слишком общего решения.
+1!
Так и я говорю, что STL слишком общая (абстрактная) библиотека
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Здравствуйте, Андрей Тарасевич, я писал:
АТ>>В общес случае — нельзя. Но это ограничение имеет свои оправдания, свои плюсы и минусы. Странно видеть его в качестве "минуса".
E>...Интересно бы узнать плюсы такого ограничения, например E> АТ>>99% целых типов в профессионально написаной среднестатистической программе должны являться беззнаковыми. Знаковые типы используются только в исключительных случаях. E>А вот это совсем интересно. Всё-таки чем так сильно C++ отличается от остальных процедурных и ООП языков? Почему-то в остальных вполне получается писать хорошие программы вообще без использования беззнаковых целых, и только на C++ 99% должны быть беззнаковыми?
E>Ещё интересно, как ты обходишься без типа unsigned double. Тяжело наверное?..
E> E>Выводы: E>А выводы-то всё те же. Что мы видим с вами? E>А вилим мы то, что STL очень заточен под идеологически правильные споры, под написание сверхкорректного кода каких-то мифических прекрасных сэмплов, каким-то не менее мифическими сверхвысококвалифицированными, сверхвнимательными и сверхаккуратными программистами. E>Либо для обучения этих спецов (конечно, ещё Суворов говаривал, что в учении должно быть тяжело
E>А для тех, кто хочет что-то такое программировать в практических целях, например, чтобы продать, STL не выгодный какой-то. Так как далёк он от практики. Вопросы, которые важны для кого-то, кто пишет программы на практике, не являются минусами или являются особенностями реализации (ну вот есть у тебя такая особенность. А делать-то чего? , как будто реализация не может угробить и прекрасную идею ), операции со строками не важны, важно, чтобы можно было родить строку из любых объектов. Напрмиер из умныз указателей на открытые файлы, скажем, ну и так далее и тому подобное
А с чем ты собственно несогласен и почему не стал это писать, равно как и отвечать на выделенные вопросы?
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Здравствуйте, Шахтер, Вы писали:
Ш>Здравствуйте, Tom, Вы писали:
S>>>>В действительности, даже такие структуры как std::map<string> достаточно быстры, Ш>>>"За такие структуры у нас увольняют." (c) мой Tom>>А можно по подробнее?
Ш>Для хранения строк обычно используют всё-таки хеш таблицы, а не деревья. Ш>Кроме того, string может иметь дорогой оператор копирования. Именно поэтому его нельзя использовать для работы с большим массивом строк. Ш>Плюс фрагментация памяти.
вопрос был почему увольняют а не почему хэш таблица лечше мапа.
Tom wrote: > Ш>Для хранения строк обычно используют всё-таки хеш таблицы, а не деревья. > Ш>Кроме того, string может иметь дорогой оператор копирования. Именно > поэтому его нельзя использовать для работы с большим массивом строк. > Ш>Плюс фрагментация памяти. > > вопрос был почему увольняют а не почему хэш таблица лечше мапа.
Ага, я тоже так и не понял. Мало того, выяснилось, что хаш-таблица слегка тяжелее мапа, т.к. помимо самих строк,
хранятся ещё и хеши. А разница лишь в сложности поиска по ключу.
Posted via RSDN NNTP Server 2.0
но это не зря, хотя, может быть, невзначай
гÅрмония мира не знает границ — сейчас мы будем пить чай
Здравствуйте, ., Вы писали:
.>Ага, я тоже так и не понял. Мало того, выяснилось, что хаш-таблица слегка тяжелее мапа, т.к. помимо самих строк, .>хранятся ещё и хеши. А разница лишь в сложности поиска по ключу.
скорее всего за злостное нарушение должностной инструкции. Но это так, мысли над ГК. А так лучше конечно дождаться ответа Шахтёра
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Здравствуйте, Tonal-, Вы писали: T>А если серьёзно, то это расширение gcc всего лишь синтаксическая надстройка над alloca+placement new. T>Сочинить собственный велосипед в эту тему — тривиально.
В MSVC6 лучше не использовать alloca. У меня был случай:
В Debug-конфигурации всё работало, но в Release-конфигурации компилятор почему-то встроил (inline) функцию SmallFunc. Во время работы программы stack исчерпывался (по умолчанию резервируется мегабайт виртуальных адресов) и возбуждалось stack overflow.
Здравствуйте, Пётр Седов, Вы писали:
ПС>В Debug-конфигурации всё работало, но в Release-конфигурации компилятор почему-то встроил (inline) функцию SmallFunc. Во время работы программы stack исчерпывался (по умолчанию резервируется мегабайт виртуальных адресов) и возбуждалось stack overflow.
ничего удивительного в эжтом всём нет. Современные компиляторы (и даже VC6 ) пытаются использовать всю доступную в месте вызова инфу о теле функции. alloca вообще лучше в C++ не использовать. Есть намного более удачные техники...
Ну и где-то по ходу пьесы пишешь такие буфера и всё
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Здравствуйте, ., Вы писали:
.>Немного не вник, а чем это лучше std::vector<char>?
Потому и возник вопрос.
Отличеи вот в этом:
char buffer[standardBufferSize];
.>Потом, дело не в буферах, а в том, что alloca использует стек, а не динамическую память. А следовательно, по идее, .>должно быть быстрее.
А CAutoBuffer тоже использует стэк...
Идея такая, что для конкретного места в коде, где тебе хочется поиспользовать alloca пишешь
CAutoBuffer<CommonCaseBufferSize> bufferHolder;
void* const buffer = bufferHolder.Reserve( currentCaseBufferSize );
// Тут используем буфер, как нам надо...
В результате пока размер запроса типичный всё хорошо, мы работаем как на alloca, а если вдруг случится слишком большой запрос, то мы аллокируем память из кучи, а потом освободим её.
Коенчно можно сделать хитрый allocator для std::vector, но это, ИМХО, менее понятно, удобно. Кроме того человек, которому я давал совет, вроде бы не в восторге от STL.
Ну и главное. Если бы я привел пример с аллоктором STL, то ещё меньше было бы шансов что-то понять
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Здравствуйте, Tom, Вы писали:
Tom>Здравствуйте, Шахтер, Вы писали:
Ш>>Здравствуйте, Tom, Вы писали:
S>>>>>В действительности, даже такие структуры как std::map<string> достаточно быстры, Ш>>>>"За такие структуры у нас увольняют." (c) мой Tom>>>А можно по подробнее?
Ш>>Для хранения строк обычно используют всё-таки хеш таблицы, а не деревья. Ш>>Кроме того, string может иметь дорогой оператор копирования. Именно поэтому его нельзя использовать для работы с большим массивом строк. Ш>>Плюс фрагментация памяти.
Tom>вопрос был почему увольняют а не почему хэш таблица лечше мапа.
Вообще это шутка конечно, но не совсем.
Этим летом был у меня на практике один студент.
Дал я ему несложную задачу -- реализовать FFT.
Он его реализовал так, что работало медленнее прямой реализации FT.
Причина -- в бездумном использовании STL.
Вот тогда то и родилась эта фраза.
STL в руках начинающего программиста -- орудие страшной разрушительной силы.
Человек, который пришел работать, должен делать что-то полезное.
Если он начинает делать что-то вредное (а STL как ни странно этому очень способствует), то наверно такой человек в коллективе не нужен.
Мне известны несколько реальных примеров когда серьёзные проекты были безнадежно испорчены благодаря STL, приходилось код выбрасывать на помойку и переделывать.
Шахтер wrote:
> STL в руках начинающего программиста -- орудие страшной разрушительной силы. > Человек, который пришел работать, должен делать что-то полезное. > Если он начинает делать что-то вредное (а STL как ни странно этому очень > способствует), то наверно такой человек в коллективе не нужен. > > Мне известны несколько реальных примеров когда серьёзные проекты были > безнадежно испорчены благодаря STL, приходилось код выбрасывать на > помойку и переделывать.
Да, согласен. Вещь тяжелая для начинающих. Но вообще говоря сам язык такой. Мне до сих пор с ужасом вспоминается
char *sLoop = new char[4];
_itoa(i, sLoop, 10);
string strField = fp1 + sLoop + fp2;
char *str = new char[255];
for (int i=0; i<=sizeof(strField); i++)
str[i] = strField[i];
_bstr_t impFieldName(str);
// думаю, очевдно, что delete нигде не было. ;)
Posted via RSDN NNTP Server 2.0
но это не зря, хотя, может быть, невзначай
гÅрмония мира не знает границ — сейчас мы будем пить чай
Здравствуйте, ., Вы писали:
.>Smal wrote:
>> Это что за хоррор? .>Да один начинающий погроммист однажды мне выдал в моём проекте.
Ну дык тут не незнание STL. Здесь непонимание C++ как такового.
Особенно порадовало .>for (int i=0; i<=sizeof(strField); i++)
Здравствуйте, Шахтер, Вы писали:
Ш>Здравствуйте, Tom, Вы писали:
Tom>>Здравствуйте, Шахтер, Вы писали:
Ш>>>Здравствуйте, Tom, Вы писали:
S>>>>>>В действительности, даже такие структуры как std::map<string> достаточно быстры, Ш>>>>>"За такие структуры у нас увольняют." (c) мой Tom>>>>А можно по подробнее?
Ш>>>Для хранения строк обычно используют всё-таки хеш таблицы, а не деревья. Ш>>>Кроме того, string может иметь дорогой оператор копирования. Именно поэтому его нельзя использовать для работы с большим массивом строк. Ш>>>Плюс фрагментация памяти.
Tom>>вопрос был почему увольняют а не почему хэш таблица лечше мапа.
Ш>Вообще это шутка конечно, но не совсем.
Ш>Этим летом был у меня на практике один студент. Ш>Дал я ему несложную задачу -- реализовать FFT. Ш>Он его реализовал так, что работало медленнее прямой реализации FT. Ш>Причина -- в бездумном использовании STL.
Ш>Вот тогда то и родилась эта фраза.
Ш>STL в руках начинающего программиста -- орудие страшной разрушительной силы. Ш>Человек, который пришел работать, должен делать что-то полезное. Ш>Если он начинает делать что-то вредное (а STL как ни странно этому очень способствует), то наверно такой человек в коллективе не нужен.
Ш>Мне известны несколько реальных примеров когда серьёзные проекты были безнадежно испорчены благодаря STL, приходилось код выбрасывать на помойку и переделывать.
Smal wrote:
>> > Это что за хоррор? > .>Да один начинающий погроммист однажды мне выдал в моём проекте. > Ну дык тут не незнание STL. Здесь непонимание C++ как такового.
В том-то и дело. Имхо незнание STL обычно основывается на непонимании C++. Хотя всякие абстрактные понятия как
ассоциативный контейнер, итератор, аллокатор и т.п. тоже необходимы, но это опять же не относится непосредственно к
самой STL.
> Особенно порадовало
Ага. А меня как радовало. Ведь такой код работал... иногда.
Posted via RSDN NNTP Server 2.0
но это не зря, хотя, может быть, невзначай
гÅрмония мира не знает границ — сейчас мы будем пить чай
Здравствуйте, Erop, Вы писали: T>>А в этом разрезе, отрицательные величины как-то странненько смотряться. T>>Чем поведение контейнера при адресации [-10] должно отличаться от [4294967286]? E>У индексов есть два момента. E>1) нередко бывает так, что в процессе итерации удобно выходить за границу массива, что и показывает, что пора заканчивать итерацию E>2) Бывает таки так, что индексы участвуют в вычислениях. Например часто хочется узнать какой из индексов больше и на сколько . Или храниить какие-то диапазоны индексов, которые легко могут выходить за область индексов массива.
random access iterator решают эти проблему, не так ли?
E>>>Ещё пример такого числа -- координаты точки (например на экране): x и y. E>>Вдруг я кусок окна задвину за границу экрана? T>>Опять же, часто ли ты эти отрицательные координаты используються для индексации массива? E>Ну экран запросто можно считать двумерным массивом пикселей (в приниципе он им и является). E>И хотя реальных обращений к экрану, за его пределами не выполняется, тем н менее координаты окон на экране удобно иметь знаковыми, хотя и не все координаты "пикселей" в таких окнах будут валидными. Зато мы сможем оперировать с окнами, у которых на экране находится только часть...
Я, я как то работал с окошкаим и пикселями!
И получалось, что координаты внутри окна, всегда только положительные.
А когда выводим окно на экран, то снача вычисляем то, что выводить будем (клипирование называется).
Опять же итерирования по отричательным координатам нет.
E>>>Ну и так дадее. Совершенно повсеместно. Специально для случая с индексом я приведу тебе один пример. А вообще-то был тут где-то недалеко здоровычй флейм про беззнаковые числа. Пиши туда? E>>>
for( int i = myArr.Size() - 5; i >= 0; i -= step )
E>>> sum += myArr[i];
T>>Чуть длиннее: T>>
if (myArr.Size() > 5)
T>> accumulate(advance(myArr.rbegin(), 5), myArr.rend(); sum);
E>Э-э-э а где тут слово srep?
Тут пргнал. Звиняйте step не заметил.
Как правильно сказал Roman Odaisky
проблему можно просто решить.
Причём решение подойдёт для всех stl контейнеров.
А вот как вы это будете для дерева и списка рисовать, и как, потом кто-то сможет понять, что делает эта куча кода...
Хотя, если подобных вычислений много, то может быть вам нужна библиотека работы с векторами и матрицами? Boost.uBLAS, например?
T>>По моему, проблема тут таки не в STL, а в некотором смешении понятий: T>>Целое число как абцисса и как индекс в массиве это совершенно разные типы. T>>В первом случае знак вполне осмыслен, во втором нет. E>А в чём разница?
В том, что массив всегда имеет конечный положительный размер, и начинается с 0го элемента?
T>>Код с итераторами действительно становиться более безопасный в плане выхода за граници, как только это понимаешь. E>Он не только более безопасный, но ещё и менее гибкий
У каждого свои недостатки. E>А вообще-то я согласен, что вопрос о беззнаковых индексах и о итераторах связан, но не так прямо E>тут уже была больискошая дискуссия на эту тему
лучше флеймить там
Ок.
E>>>>> E>А что касается "более быстрого и компактного кода с шаблонами", то у меня есть такое вот наблюдение над задачами, которые реально возникают даже при разработке очень очень сложных и наукоёмких программ. Такие проблемы, ИМХО, хорошо решаются в следующем порядке
E>1) Если можно как-то просто и естественно сделать без виртуальных функций, то это решение оказывается самым хорошим, быстрым и поддерживаемым. E>2) Если п. 1 не получился, а с виртуальными функциями, но без шаблонов, таки получается сделать как-то естественно и просто, то обычно это и есть хорошее решение. E>3) Если и 1 и 2 не прошли, то значит задача реально небанальная. И, возможно, приминив шаблоны её удастся решить приемлемо неплохо.
У меня есть несколько другое наблюдение:
Было написано 2 движка векторного графического редактора.
В разное время для подобных задачь.
Первый использовал в основном шаблоны, второй виртуальность.
Скорость отрисовки отличалась примерно в 2-3 раза, хотя второй работал с несколько более простыми данными.
К сожалению отношение простоты и понятности мне оценивать трудно — по причине авторства.
Но оба успешно работают до сих пор в промыщленных системах.
M>В одном конкретном случае зачастую проще свилосипедствовать, чем разбираться с алгоритмом STL или с особенностями контейнеров. Зачастую быстрее написать алгоритм чем искать его в справочнике (в смысле в хелпе). Кароче надо довольно длинный список в голове держать. Если, скажем, ф-я поиска подстроки есть всегда и везде, то реализовывать её самому мне в голову не придёт, а вот тотже find_if: "ХЗ — есть эта фича в STL или нет — быстрее самому написать. Может я её ещё и не запинаю в своём случае". Нет в СТЛ какой-то структурировнности, что-ли. Какого-то простого правила — "Вот это точно должно быть в СТЛ, а вот это — не стоит и искать там".